diff --git a/src/i830_driver.c b/src/i830_driver.c index 7818ee4..12bee22 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2291,6 +2291,138 @@ I830BlockHandler(int i, I830VideoBlockHandler(i, blockData, pTimeout, pReadmask); } +/* + * Try to allocate memory in several ways: + * 1) If direct rendering is enabled, try to allocate enough memory for tiled + * surfaces by rounding up the display width to a tileable one. + * 2) If that fails or the allocations themselves fail, try again with untiled + * allocations (if this works DRI will stay enabled). + * 3) And if all else fails, disable DRI and try just 2D allocations. + * 4) Give up and fail ScreenInit. + */ +static Bool +i830_memory_init(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + int savedDisplayWidth = pScrn->displayWidth; + int i; + Bool tiled = FALSE; + + if (pI830->directRenderingEnabled && 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; + } + } + } + } + + /* 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, + "Couldn't initialize video memory allocator\n"); + PreInitCleanup(pScrn); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, + pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, + "VideoRam: %d KB\n", pScrn->videoRam); + + if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES, + &(pI830->CacheLines))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n", + pI830->CacheLines); + } else { + pI830->CacheLines = -1; + } + + if (!tiled) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to find a tileable pitch, " + "falling back to untiled allocation.\n"); + goto allocate_untiled; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Attempting memory allocation with tiled buffers.\n"); + if (pScrn->displayWidth != savedDisplayWidth) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Increasing the scanline pitch for tiled allocation " + "(%d -> %d).\n", + savedDisplayWidth, pScrn->displayWidth); + } + + if (!i830_allocate_2d_memory(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to allocate tiled 2D " + "objects. Falling back to untiled allocation.\n"); + goto allocate_untiled; + } + if (!i830_allocate_3d_memory(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to allocate tiled 3D " + "objects. Falling back to untiled allocation.\n"); + goto allocate_untiled; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Tiled allocation successful.\n"); + return TRUE; + +allocate_untiled: + pI830->tiling = FALSE; + pScrn->displayWidth = savedDisplayWidth; + if (pI830->allowPageFlip) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Couldn't allocate tiled memory, page flipping " + "disabled\n"); + pI830->allowPageFlip = FALSE; + if (pI830->fb_compression) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Couldn't allocate tiled memory, fb compression " + "disabled\n"); + pI830->fb_compression = FALSE; + + if (!i830_allocate_2d_memory(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to allocate untiled 2D " + "objects. Disabling DRI.\n"); + goto allocate_no_dri; + } + if (!i830_allocate_3d_memory(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to allocate untiled 3D " + "objects. Disabling DRI.\n"); + goto allocate_no_dri; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Untiled allocation successful.\n"); + return TRUE; + +allocate_no_dri: + i830_reset_allocations(pScrn); + pI830->directRenderingEnabled = FALSE; + + if (i830_allocate_2d_memory(pScrn)) + return TRUE; + + return FALSE; +} + static Bool I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { @@ -2300,8 +2432,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) VisualPtr visual; I830Ptr pI8301 = NULL; unsigned long sys_mem; - int i, c; - Bool allocation_done = FALSE; + int c; MessageType from; #ifdef XF86DRI xf86CrtcConfigPtr config; @@ -2416,26 +2547,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->directRenderingEnabled = FALSE; #endif - /* 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, - "Couldn't initialize video memory allocator\n"); - PreInitCleanup(pScrn); - return FALSE; - } - - xf86DrvMsg(pScrn->scrnIndex, - pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, - "VideoRam: %d KB\n", pScrn->videoRam); - - if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES, - &(pI830->CacheLines))) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n", - pI830->CacheLines); - } else { - pI830->CacheLines = -1; - } - /* Enable tiling by default */ pI830->tiling = TRUE; @@ -2495,13 +2606,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Need MMIO mapped to do GTT lookups during memory allocation. */ I830MapMMIO(pScrn); -#if defined(XF86DRI) - /* - * If DRI is potentially usable, check if there is enough memory available - * for it, and if there's also enough to allow tiling to be enabled. - */ - - #ifdef I830_XV /* * Set this so that the overlay allocation is factored in when @@ -2510,100 +2614,11 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->XvEnabled = !pI830->XvDisabled; #endif - if (pI830->directRenderingEnabled) { - int savedDisplayWidth = pScrn->displayWidth; - Bool tiled = FALSE; - - 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; - } - } - } - - /* Attempt two rounds of allocation to get 2d and 3d memory to fit: - * - * 0: untiled - * 1: tiled - */ - -#define MM_TURNS 2 - for (i = 0; i < MM_TURNS; i++) { - if (!tiled && i == 0) - continue; - - if (i >= 1) { - /* For further allocations, disable tiling */ - pI830->tiling = FALSE; - pScrn->displayWidth = savedDisplayWidth; - if (pI830->allowPageFlip) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Couldn't allocate tiled memory, page flipping " - "disabled\n"); - pI830->allowPageFlip = FALSE; - if (pI830->fb_compression) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Couldn't allocate tiled memory, fb compression " - "disabled\n"); - pI830->fb_compression = FALSE; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Attempting memory allocation with %s buffers.\n", - (i & 1) ? "untiled" : "tiled"); - - if (i830_allocate_2d_memory(pScrn) && - i830_allocate_3d_memory(pScrn)) - { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Success.\n"); - if (pScrn->displayWidth != savedDisplayWidth) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Increasing the scanline pitch to allow tiling mode " - "(%d -> %d).\n", - savedDisplayWidth, pScrn->displayWidth); - } - allocation_done = TRUE; - break; - } - - i830_reset_allocations(pScrn); - } - - if (i == MM_TURNS) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Not enough video memory. Disabling DRI.\n"); - pI830->directRenderingEnabled = FALSE; - } - } -#endif - - if (!allocation_done) { - if (!i830_allocate_2d_memory(pScrn)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't allocate video memory\n"); - return FALSE; - } - allocation_done = TRUE; - } + if (!i830_memory_init(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate video memory\n"); + return FALSE; + } I830UnmapMMIO(pScrn); diff --git a/src/i830_memory.c b/src/i830_memory.c index 85b6528..a36407e 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -464,7 +464,7 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) ROUND_TO(HWCURSOR_SIZE_ARGB, GTT_PAGE_SIZE)); } if (pI830->fb_compression) - mmsize -= MB(6); + mmsize -= MB(6) + ROUND_TO_PAGE(FBC_LL_SIZE + FBC_LL_PAD); /* Can't do TTM on stolen memory */ mmsize -= pI830->stolen_size;