summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJesse Barnes <jesse.barnes@intel.com>2008-03-06 19:24:47 +0800
committerZhenyu Wang <zhenyu.z.wang@intel.com>2008-03-06 19:24:47 +0800
commit750beb9232b51223d8e650878ce8dad071f0d0b3 (patch)
tree715b556bac886ae66a4e974cdb0add937a780a3b /src
parentd466b25d09bbe85abe84d9d7714ffb65fafe7593 (diff)
Refactor memory allocation into a separate function
This simplifies the memory allocation code and fixes a number of bugs. Prior to this change, some flags may have been set after memory allocation occurred, meaning they had no effect. It should also make the allocation logic clearer.
Diffstat (limited to 'src')
-rw-r--r--src/i830_driver.c276
1 files changed, 147 insertions, 129 deletions
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5cd0a34b..0aaf9df0 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2366,6 +2366,141 @@ I830BlockHandler(int i,
}
static Bool
+i830_try_memory_allocation(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ Bool tiled = pI830->tiling;
+ Bool dri = pI830->directRenderingEnabled;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Attempting memory allocation with %stiled buffers.\n",
+ tiled ? "" : "un");
+
+ if (!i830_allocate_2d_memory(pScrn))
+ goto failed;
+
+ if (dri && !i830_allocate_3d_memory(pScrn))
+ goto failed;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%siled allocation successful.\n",
+ tiled ? "T" : "Unt");
+ return TRUE;
+
+failed:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%siled allocation failed.\n",
+ 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
+ * 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;
+
+ /*
+ * 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;
+ }
+ }
+ }
+ }
+ /* 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;
+ }
+
+ /* Tiled first if we got a good displayWidth */
+ if (tiled) {
+ if (i830_try_memory_allocation(pScrn))
+ return TRUE;
+ else {
+ i830_reset_allocations(pScrn);
+ pI830->tiling = FALSE;
+ }
+ }
+
+ /* If tiling fails we have to disable page flipping & FBC */
+ 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;
+
+ /* Try again, but leave DRI enabled */
+ if (pI830->directRenderingEnabled) {
+ if (i830_try_memory_allocation(pScrn))
+ return TRUE;
+ else {
+ i830_reset_allocations(pScrn);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Couldn't allocate 3D memory, "
+ "disabling DRI.\n");
+ pI830->directRenderingEnabled = FALSE;
+ }
+ }
+
+ if (i830_try_memory_allocation(pScrn))
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool
I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
ScrnInfoPtr pScrn;
@@ -2374,8 +2509,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;
@@ -2490,26 +2624,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;
@@ -2567,16 +2681,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->last_3d = pI8301->last_3d;
}
- /* 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
@@ -2585,103 +2689,6 @@ 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;
- }
-
- I830UnmapMMIO(pScrn);
-
if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Cannot support DRI with frame buffer width > 2048.\n");
@@ -2689,6 +2696,17 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->directRenderingEnabled = FALSE;
}
+ /* Need MMIO mapped to do GTT lookups during memory allocation. */
+ I830MapMMIO(pScrn);
+
+ if (!i830_memory_init(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't allocate video memory\n");
+ return FALSE;
+ }
+
+ I830UnmapMMIO(pScrn);
+
#ifdef HAS_MTRR_SUPPORT
{
int fd;