Signed-off-by: Keith Packard <kei...@keithp.com>
---
 src/i830.h         |    9 +++
 src/i830_display.c |   31 +++++++++--
 src/i830_display.h |    1 +
 src/i830_driver.c  |  149 ++++++++++++++++++++++++++++++++++++++-------------
 src/i830_exa.c     |   27 +++++++++
 src/i830_memory.c  |  120 +++--------------------------------------
 6 files changed, 184 insertions(+), 153 deletions(-)

diff --git a/src/i830.h b/src/i830.h
index fe7c8b2..d5b0e5d 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -95,6 +95,7 @@ void i830_uxa_block_handler (ScreenPtr pScreen);
 
 #if defined(I830_USE_UXA) || defined(I830_USE_EXA)
 dri_bo *i830_get_pixmap_bo (PixmapPtr pixmap);
+void i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo);
 #endif
 
 #ifdef I830_USE_XAA
@@ -273,6 +274,8 @@ typedef struct _I830CrtcPrivateRec {
     
     int                            dpms_mode;
     
+    int                            x, y;
+
     /* Lookup table values to be set when the CRTC is enabled */
     uint8_t lut_r[256], lut_g[256], lut_b[256];
 
@@ -476,6 +479,8 @@ typedef struct _I830Rec {
    int drmMinor;
    Bool allocate_classic_textures;
 
+   Bool can_resize;
+
    Bool want_vblank_interrupts;
 #ifdef DAMAGE
    DamagePtr pDamage;
@@ -915,6 +920,10 @@ Bool i830_unbind_all_memory(ScrnInfoPtr pScrn);
 Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
 Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
 
+i830_memory *
+i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
+                         Bool secondary);
+
 /* i830_modes.c */
 DisplayModePtr i830_ddc_get_modes(xf86OutputPtr output);
 
diff --git a/src/i830_display.c b/src/i830_display.c
index e3236c9..a4af8ad 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -387,12 +387,14 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
     I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
     int pipe = intel_crtc->pipe;
     int plane = intel_crtc->plane;
-    unsigned long Start, Offset;
+    unsigned long Start, Offset, Stride;
     int dspbase = (plane == 0 ? DSPABASE : DSPBBASE);
     int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF);
     int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
+    int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
 
     Offset = ((y * pScrn->displayWidth + x) * pI830->cpp);
+    Stride = pScrn->displayWidth * pI830->cpp;
     if (pI830->front_buffer == NULL) {
        /* During startup we may be called as part of monitor detection while
         * there is no memory allocation done, so just supply a dummy base
@@ -403,6 +405,7 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
        /* offset is done by shadow painting code, not here */
        Start = (char *)crtc->rotatedData - (char *)pI830->FbBase;
        Offset = 0;
+       Stride = intel_crtc->rotate_mem->pitch;
     } else if (I830IsPrimary(pScrn)) {
        Start = pI830->front_buffer->offset;
     } else {
@@ -410,6 +413,10 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
        Start = pI8301->front_buffer_2->offset;
     }
 
+    crtc->x = x;
+    crtc->y = y;
+
+    OUTREG(dspstride, Stride);
     if (IS_I965G(pI830)) {
         OUTREG(dspbase, Offset);
        POSTING_READ(dspbase);
@@ -1199,7 +1206,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
     int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
     int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
     int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
-    int dspstride_reg = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
     int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
     int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
     int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT;
@@ -1495,7 +1501,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
        ((adjusted_mode->CrtcVBlankEnd - 1) << 16));
     OUTREG(vsync_reg, (adjusted_mode->CrtcVSyncStart - 1) |
        ((adjusted_mode->CrtcVSyncEnd - 1) << 16));
-    OUTREG(dspstride_reg, pScrn->displayWidth * pI830->cpp);
     /* pipesrc and dspsize control the size that is scaled from, which should
      * always be the user's requested size.
      */
@@ -1644,10 +1649,28 @@ i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr 
rotate_pixmap, void *data)
 static void
 i830_crtc_set_origin(xf86CrtcPtr crtc, int x, int y)
 {
-    i830PipeSetBase(crtc, x, y);
+    if (crtc->enabled)
+       i830PipeSetBase(crtc, x, y);
 }
 #endif
 
+/* The screen bo has changed, reset each active crtc to point at
+ * the same location that it currently points at, but in the new bo
+ */
+void
+i830_set_new_crtc_bo(ScrnInfoPtr pScrn)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int                        i;
+
+    for (i = 0; i < xf86_config->num_crtc; i++) {
+       xf86CrtcPtr crtc = xf86_config->crtc[i];
+
+       if (crtc->enabled && !crtc->transform_in_use)
+           i830PipeSetBase(crtc, crtc->x, crtc->y);
+    }
+}
+
 void
 i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
 {
diff --git a/src/i830_display.h b/src/i830_display.h
index 1eeb7f1..8d767b1 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -31,6 +31,7 @@
 void i830PipeSetBase(xf86CrtcPtr crtc, int x, int y);
 void i830WaitForVblank(ScrnInfoPtr pScrn);
 void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn);
+void i830_set_new_crtc_bo(ScrnInfoPtr pScrn);
 
 xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output, DisplayModePtr mode, 
int *dpms_mode);
 void i830ReleaseLoadDetectPipe(xf86OutputPtr output, int dpms_mode);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index d3b539a..358b485 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1085,11 +1085,108 @@ I830IsPrimary(ScrnInfoPtr pScrn)
    return TRUE;
 }
 
+
+/*
+ * Adjust *width to allow for tiling if possible
+ */
+Bool
+i830_tiled_width(I830Ptr i830, int *width, int cpp)
+{
+    Bool    tiled = FALSE;
+
+    /*
+     * Adjust the display width to allow for front buffer tiling if possible
+     */
+    if (i830->tiling) {
+       if (IS_I965G(i830)) {
+           int tile_pixels = 512 / cpp;
+           *width = (*width + tile_pixels - 1) &
+               ~(tile_pixels - 1);
+           tiled = TRUE;
+       } else {
+           /* Good pitches to allow tiling.  Don't care about pitches < 1024
+            * pixels.
+            */
+           static const int pitches[] = {
+               1024,
+               2048,
+               4096,
+               8192,
+               0
+           };
+           int i;
+
+           for (i = 0; pitches[i] != 0; i++) {
+               if (pitches[i] >= *width) {
+                   *width = pitches[i];
+                   tiled = TRUE;
+                   break;
+               }
+           }
+       }
+    }
+    return tiled;
+}
+
+/*
+ * Pad to accelerator requirement
+ */
+int
+i830_pad_drawable_width(int width, int cpp)
+{
+    return (width + 63) & ~63;
+}
+
 static Bool
 i830_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 {
+    I830Ptr    i830 = I830PTR(scrn);
+    int                old_x = scrn->virtualX;
+    int                old_y = scrn->virtualY;
+    int                old_width = scrn->displayWidth;
+
+    if (old_x == width && old_y == height)
+       return TRUE;
+
     scrn->virtualX = width;
     scrn->virtualY = height;
+#ifdef DRI2
+    if (i830->can_resize && i830->front_buffer)
+    {
+       i830_memory *new_front, *old_front;
+       BoxRec      mem_box;
+       Bool        tiled;
+       ScreenPtr   screen = screenInfo.screens[scrn->scrnIndex];
+
+       scrn->displayWidth = i830_pad_drawable_width(width, i830->cpp);
+       tiled = i830_tiled_width(i830, &scrn->displayWidth, i830->cpp);
+       xf86DrvMsg(scrn->scrnIndex, X_INFO, "Allocate new frame buffer %dx%d 
stride %d\n",
+                  width, height, scrn->displayWidth);
+       I830Sync(scrn);
+       i830WaitForVblank(scrn);
+       new_front = i830_allocate_framebuffer(scrn, i830, &mem_box, FALSE);
+       if (!new_front) {
+           scrn->virtualX = old_x;
+           scrn->virtualY = old_y;
+           scrn->displayWidth = old_width;
+           return FALSE;
+       }
+       old_front = i830->front_buffer;
+       i830->front_buffer = new_front;
+       i830_set_pixmap_bo(screen->GetScreenPixmap(screen),
+                          new_front->bo);
+       scrn->fbOffset = i830->front_buffer->offset;
+       screen->ModifyPixmapHeader(screen->GetScreenPixmap(screen),
+                                  width, height, -1, -1, scrn->displayWidth * 
i830->cpp,
+                                  NULL);
+       xf86DrvMsg(scrn->scrnIndex, X_INFO, "New front buffer at 0x%lx\n",
+                  i830->front_buffer->offset);
+       i830_set_new_crtc_bo(scrn);
+       I830Sync(scrn);
+       i830WaitForVblank(scrn);
+       i830_free_memory(scrn, old_front);
+    }
+#endif
     return TRUE;
 }
 
@@ -1487,8 +1584,7 @@ I830PreInitCrtcConfig(ScrnInfoPtr pScrn)
     /* See i830_exa.c comments for why we limit the framebuffer size like this.
      */
     if (IS_I965G(pI830)) {
-       max_width = 8192;
-       max_height = 8192;
+       max_height = max_width = min(16384 / pI830->cpp, 8192);
     } else {
        max_width = 2048;
        max_height = 2048;
@@ -1595,7 +1691,16 @@ I830AccelMethodInit(ScrnInfoPtr pScrn)
     I830SetupOutputs(pScrn);
 
     SaveHWState(pScrn);
-    if (!xf86InitialConfiguration (pScrn, FALSE))
+    pI830->can_resize = FALSE;
+    if (pI830->accel == ACCEL_UXA && pI830->directRenderingType != DRI_XF86DRI)
+       pI830->can_resize = TRUE;
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+              "Resizable framebuffer: %s (%d %d)\n",
+              pI830->can_resize ? "available" : "not available",
+              pI830->directRenderingType, pI830->accel);
+
+    if (!xf86InitialConfiguration (pScrn, pI830->can_resize))
     {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
        RestoreHWState(pScrn);
@@ -2760,7 +2865,6 @@ failed:
            tiled ? "T" : "Unt");
     return FALSE;
 }
-
 /*
  * Try to allocate memory in several ways:
  *  1) If direct rendering is enabled, try to allocate enough memory for tiled
@@ -2775,39 +2879,9 @@ i830_memory_init(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     int savedDisplayWidth = pScrn->displayWidth;
-    int i;
     Bool tiled = FALSE;
 
-    /*
-     * Adjust the display width to allow for front buffer tiling if possible
-     */
-    if (pI830->tiling) {
-       if (IS_I965G(pI830)) {
-           int tile_pixels = 512 / pI830->cpp;
-           pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) &
-               ~(tile_pixels - 1);
-           tiled = TRUE;
-       } else {
-           /* Good pitches to allow tiling.  Don't care about pitches < 1024
-            * pixels.
-            */
-           static const int pitches[] = {
-               1024,
-               2048,
-               4096,
-               8192,
-               0
-           };
-
-           for (i = 0; pitches[i] != 0; i++) {
-               if (pitches[i] >= pScrn->displayWidth) {
-                   pScrn->displayWidth = pitches[i];
-                   tiled = TRUE;
-                   break;
-               }
-           }
-       }
-    }
+    tiled = i830_tiled_width(pI830, &pScrn->displayWidth, pI830->cpp);
     /* Set up our video memory allocator for the chosen videoRam */
     if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -3028,7 +3102,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int 
argc, char **argv)
    if (!pI830->use_drm_mode)
        hwp = VGAHWPTR(pScrn);
 
-   pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
+   pScrn->displayWidth = i830_pad_drawable_width(pScrn->virtualX, pI830->cpp);
 
    /*
     * The "VideoRam" config file parameter specifies the maximum amount of
@@ -3092,8 +3166,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int 
argc, char **argv)
     */
    if (pI830->directRenderingType == DRI_NONE && pI830->SWCursor)
        pI830->directRenderingType = DRI_DISABLED;
-
-   if (pI830->directRenderingType == DRI_NONE && I830DRIScreenInit(pScreen))
+   if (!pI830->can_resize && pI830->directRenderingType == DRI_NONE && 
I830DRIScreenInit(pScreen))
        pI830->directRenderingType = DRI_XF86DRI;
 
    if (pI830->directRenderingType == DRI_XF86DRI) {
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 3e3487e..ee279d5 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -758,6 +758,32 @@ i830_get_pixmap_bo(PixmapPtr pixmap)
     return NULL;
 }
 
+void
+i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pixmap->drawable.pScreen->myNum];
+    I830Ptr i830 = I830PTR(pScrn);
+    dri_bo  *old_bo = i830_get_pixmap_bo (pixmap);
+
+    if (old_bo)
+       dri_bo_unreference (old_bo);
+#if I830_USE_UXA
+    if (i830->accel == ACCEL_UXA) {
+       dri_bo_reference(bo);
+       dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
+    }
+#endif
+#ifdef XF86DRM_MODE
+    if (i830->accel == ACCEL_EXA) {
+       struct i830_exa_pixmap_priv *driver_priv =
+           exaGetPixmapDriverPrivate(pixmap);
+       if (driver_priv) {
+           dri_bo_reference(bo);
+           driver_priv->bo = bo;
+       }
+    }
+#endif
+}
 #if defined(I830_USE_UXA)
 
 static void
@@ -893,6 +919,7 @@ void i830_uxa_create_screen_resources(ScreenPtr pScreen)
     if (bo != NULL) {
        PixmapPtr   pixmap = pScreen->GetScreenPixmap(pScreen);
        i830_uxa_set_pixmap_bo (pixmap, bo);
+       dri_bo_reference(bo);
     }
 }
 
diff --git a/src/i830_memory.c b/src/i830_memory.c
index a5e7dcd..45aa109 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1128,7 +1128,7 @@ IsTileable(ScrnInfoPtr pScrn, int pitch)
  * \param pI830 I830Ptr for the screen being allocated.
  * \param FbMemBox
  */
-static i830_memory *
+i830_memory *
 i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
                          Bool secondary)
 {
@@ -1150,10 +1150,14 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr 
pI830, BoxPtr FbMemBox,
     /* We'll allocate the fb such that the root window will fit regardless of
      * rotation.
      */
-    if (!pI830->use_drm_mode && pScrn->virtualX > pScrn->virtualY)
-       fb_height = pScrn->virtualX;
-    else
-       fb_height = pScrn->virtualY;
+    fb_height = pScrn->virtualY;
+    if (!pI830->can_resize)
+    {
+       if (!pI830->use_drm_mode && pScrn->virtualX > pScrn->virtualY)
+           fb_height = pScrn->virtualX;
+       else
+           fb_height = pScrn->virtualY;
+    }
 
     FbMemBox->x1 = 0;
     FbMemBox->x2 = pScrn->displayWidth;
@@ -2123,114 +2127,8 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const 
char *name,
 }
 #endif
 
-#if 0
-static 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;
-    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));
-
-    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->accel == ACCEL_EXA) && 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;
-}
-#endif
 uint32_t
 i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch)
 {
     return 0;
-
-#if 0
-    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 %08lx, new front size %08lx\n",
-          old_buffer->bo->size, pI830->front_buffer->bo->size);
-    ErrorF("old front offset %08lx, new front offset %08lx\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
 }
-- 
1.5.6.5


------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to