On Thu, 2008-12-11 at 15:30 -0800, Keith Packard wrote:
> When running UXA (and not DRI1), we can resize the frame buffer.
> Signed-off-by: Keith Packard <kei...@keithp.com>
> ---
>  src/i830.h         |    9 +++
>  src/i830_display.c |   29 ++++++++++-
>  src/i830_display.h |    1 +
>  src/i830_driver.c  |  143 ++++++++++++++++++++++++++++++++++++++-------------
>  src/i830_exa.c     |   22 ++++++++
>  src/i830_memory.c  |   17 ++++--
>  6 files changed, 178 insertions(+), 43 deletions(-)
> 
> diff --git a/src/i830.h b/src/i830.h
> index 8ad5c69..2ab8893 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
> @@ -271,6 +272,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];
>  
> @@ -474,6 +477,8 @@ typedef struct _I830Rec {
>     int drmMinor;
>     Bool allocate_classic_textures;
>  
> +   Bool can_resize;
> +
>     Bool want_vblank_interrupts;
>  #ifdef DAMAGE
>     DamagePtr pDamage;
> @@ -910,6 +915,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 2e5d55a..b1ce9e6 100644
> --- a/src/i830_display.c
> +++ b/src/i830_display.c
> @@ -410,6 +410,9 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
>       Start = pI8301->front_buffer_2->offset;
>      }
>  
> +    crtc->x = x;
> +    crtc->y = y;
> +
>      if (IS_I965G(pI830)) {
>          OUTREG(dspbase, Offset);
>       POSTING_READ(dspbase);
> @@ -1642,10 +1645,34 @@ 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)
> +{
> +    I830Ptr pI830 = I830PTR(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) {
> +         I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
> +         int plane = intel_crtc->plane;
> +         int dspstride_reg = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
> +            OUTREG(dspstride_reg, pScrn->displayWidth * pI830->cpp);
> +         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 7590257..d366ab6 100644
> --- a/src/i830_driver.c
> +++ b/src/i830_driver.c
> @@ -1085,11 +1085,103 @@ I830IsPrimary(ScrnInfoPtr pScrn)
>     return TRUE;
>  }
>  
> +
> +/*
> + * Adjust *width to allow for tiling if possible
> + */
> +static 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
> + */
> +static int
> +i830_pad_drawable_width(int width)
> +{
> +    return (width + 63) & ~63;
> +}
> +

I know of a 64b alignment required for display planes, but I'm not sure
what a 64-pixel alignment is about.  Also, #define ALIGN() should be in
a header already, seriously.

>  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;
> +     BoxRec      mem_box;
> +     Bool        tiled;
> +     ScreenPtr   screen = screenInfo.screens[scrn->scrnIndex];
> +
> +     scrn->displayWidth = i830_pad_drawable_width(width);
> +     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);
> +     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;
> +     }
> +     i830_free_memory(scrn, 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);
> +    }
> +#endif
>      return TRUE;
>  }
>  
> @@ -1487,8 +1579,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;
> @@ -1602,7 +1693,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);
> @@ -2775,7 +2875,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
> @@ -2790,39 +2889,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,
> @@ -3043,7 +3112,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);
>  
>     /*
>      * The "VideoRam" config file parameter specifies the maximum amount of
> @@ -3105,7 +3174,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int 
> argc, char **argv)
>     /* If DRI hasn't been explicitly disabled, try to initialize it.
>      * It will be used by the memory allocator.
>      */
> -   if (pI830->directRenderingType == DRI_NONE && I830DRIScreenInit(pScreen))
> +   if (!pI830->can_resize && pI830->directRenderingType == DRI_NONE && 
> I830DRIScreenInit(pScreen))
>         pI830->directRenderingType = DRI_XF86DRI;
>  #endif
>  
> diff --git a/src/i830_exa.c b/src/i830_exa.c
> index 3e3487e..ced31a8 100644
> --- a/src/i830_exa.c
> +++ b/src/i830_exa.c
> @@ -758,6 +758,28 @@ 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)
> +     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)
> +         driver_priv->bo = bo;
> +    }
> +#endif
> +}
>  #if defined(I830_USE_UXA)
>  
>  static void
> diff --git a/src/i830_memory.c b/src/i830_memory.c
> index ca15964..132642f 100644
> --- a/src/i830_memory.c
> +++ b/src/i830_memory.c
> @@ -918,10 +918,13 @@ i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const 
> char *name,
>      mem = i830_allocate_memory(pScrn, name, aper_size, aper_align, flags);
>      if (mem == NULL)
>       return NULL;
> +    i830_unbind_memory(pScrn, mem);
>      mem->size = size;
>      mem->tiling = tile_format;
>      mem->pitch = pitch;
>      mem->fence_nr = -1;
> +    if (pScrn->vtSema || pI830->use_drm_mode)
> +     i830_bind_memory(pScrn, mem);
>  
>  #ifdef XF86DRI
>      if (mem->bo != 0) {
> @@ -1145,7 +1148,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)
>  {
> @@ -1167,10 +1170,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;
-- 
Eric Anholt
e...@anholt.net                         eric.anh...@intel.com


Attachment: signature.asc
Description: This is a digitally signed message part

------------------------------------------------------------------------------
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