diff options
author | Eric Anholt <eric@anholt.net> | 2007-01-18 14:26:21 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2007-01-18 14:26:21 -0800 |
commit | 74ebff6732b9bfcf8c865b52cbebfd9bf6b73eb2 (patch) | |
tree | 2b947b57dd9ea8d3e61a1c43455c0fd6b216b6f9 /src/i830_memory.c | |
parent | 8759f4d89a141f7d69f1894ec3059ba6bd1cf86b (diff) |
Allocate separate cursor memory per CRTC and rotate cursors appropriately.
Also, add bind/unbind of the shadow rotate buffers, which was missed in a
previous commit.
Diffstat (limited to 'src/i830_memory.c')
-rw-r--r-- | src/i830_memory.c | 206 |
1 files changed, 137 insertions, 69 deletions
diff --git a/src/i830_memory.c b/src/i830_memory.c index ae14c06c..14dacc86 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -826,6 +826,91 @@ I830AllocateRotateBuffers(xf86CrtcPtr crtc, const int flags) return TRUE; } +static Bool +I830AllocateCursorBuffers(xf86CrtcPtr crtc, const int flags) +{ + ScrnInfoPtr pScrn = crtc->scrn; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + I830Ptr pI830 = I830PTR(pScrn); + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + long size, alloced; + int cursFlags = 0; + + /* Clear cursor info */ + memset(&intel_crtc->cursor_mem, 0, sizeof(I830MemRange)); + intel_crtc->cursor_mem.Key = -1; + memset(&intel_crtc->cursor_mem_argb, 0, sizeof(I830MemRange)); + intel_crtc->cursor_mem_argb.Key = -1; + + if (pI830->SWCursor) + return FALSE; + + /* + * Mouse cursor -- The i810-i830 need a physical address in system + * memory from which to upload the cursor. We get this from + * the agpgart module using a special memory type. + */ + + size = HWCURSOR_SIZE; + cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; + if (pI830->CursorNeedsPhysical) + cursFlags |= NEED_PHYSICAL_ADDR; + + alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem, + &pI830->StolenPool, size, + GTT_PAGE_SIZE, flags | cursFlags); + if (alloced < size || + (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem.Physical)) + { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate HW cursor space.\n"); + return FALSE; + } + } else { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for HW cursor at 0x%lx", s, + alloced / 1024, intel_crtc->cursor_mem.Start); + if (pI830->CursorNeedsPhysical) { + xf86ErrorFVerb(verbosity, " (0x%08lx)", + intel_crtc->cursor_mem.Physical); + } + xf86ErrorFVerb(verbosity, "\n"); + } + + /* Allocate the ARGB cursor space. Its success is optional -- we won't set + * SWCursor if it fails. + */ + size = HWCURSOR_SIZE_ARGB; + cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; + if (pI830->CursorNeedsPhysical) + cursFlags |= NEED_PHYSICAL_ADDR; + + alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem_argb, + &pI830->StolenPool, size, + GTT_PAGE_SIZE, flags | cursFlags); + if (alloced < size || + (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem_argb.Physical)) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate HW (ARGB) cursor space.\n"); + } + } else { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for HW (ARGB) cursor at 0x%lx", s, + alloced / 1024, intel_crtc->cursor_mem_argb.Start); + if (pI830->CursorNeedsPhysical) { + xf86ErrorFVerb(verbosity, " (0x%08lx)", + intel_crtc->cursor_mem_argb.Physical); + } + xf86ErrorFVerb(verbosity, "\n"); + } + + return FALSE; +} + /* * Allocate memory for 2D operation. This includes the (front) framebuffer, * ring buffer, scratch memory, HW cursor. @@ -834,6 +919,7 @@ Bool I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) { I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); long size, alloced; Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); int verbosity = dryrun ? 4 : 1; @@ -871,8 +957,6 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) pI830->StolenPool.Free.Size); if (flags & ALLOC_INITIAL) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - if (pI830->NeedRingBufferLow) AllocateRingBuffer(pScrn, flags | FORCE_LOW); @@ -1041,63 +1125,18 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) } #endif - /* Clear cursor info */ - memset(pI830->CursorMem, 0, sizeof(I830MemRange)); - pI830->CursorMem->Key = -1; - memset(pI830->CursorMemARGB, 0, sizeof(I830MemRange)); - pI830->CursorMemARGB->Key = -1; - - if (!pI830->SWCursor) { - int cursFlags = 0; - /* - * Mouse cursor -- The i810-i830 need a physical address in system - * memory from which to upload the cursor. We get this from - * the agpgart module using a special memory type. - */ - - size = HWCURSOR_SIZE; - cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; - if (pI830->CursorNeedsPhysical) - cursFlags |= NEED_PHYSICAL_ADDR; - - alloced = I830AllocVidMem(pScrn, pI830->CursorMem, - &(pI830->StolenPool), size, - GTT_PAGE_SIZE, flags | cursFlags); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW cursor space.\n"); - } - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for HW cursor at 0x%lx", s, - alloced / 1024, pI830->CursorMem->Start); - if (pI830->CursorNeedsPhysical) - xf86ErrorFVerb(verbosity, " (0x%08lx)", pI830->CursorMem->Physical); - xf86ErrorFVerb(verbosity, "\n"); - } - - size = HWCURSOR_SIZE_ARGB; - cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; - if (pI830->CursorNeedsPhysical) - cursFlags |= NEED_PHYSICAL_ADDR; - - alloced = I830AllocVidMem(pScrn, pI830->CursorMemARGB, - &(pI830->StolenPool), size, - GTT_PAGE_SIZE, flags | cursFlags); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW (ARGB) cursor space.\n"); - } - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for HW (ARGB) cursor at 0x%lx", s, - alloced / 1024, pI830->CursorMemARGB->Start); - if (pI830->CursorNeedsPhysical) - xf86ErrorFVerb(verbosity, " (0x%08lx)", pI830->CursorMemARGB->Physical); - xf86ErrorFVerb(verbosity, "\n"); - } + if (!pI830->SWCursor && !dryrun) { + for (i = 0; i < xf86_config->num_crtc; i++) { + if (!I830AllocateCursorBuffers(xf86_config->crtc[i], flags) && + pI830->SWCursor) + { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Disabling HW cursor because the cursor memory " + "allocation failed.\n"); + pI830->SWCursor = TRUE; + break; + } + } } #ifdef I830_XV @@ -1567,6 +1606,8 @@ Bool I830FixupOffsets(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; DPRINTF(PFX, "I830FixupOffsets\n"); @@ -1574,8 +1615,15 @@ I830FixupOffsets(ScrnInfoPtr pScrn) if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) I830FixOffset(pScrn, &(pI830->FrontBuffer2)); I830FixOffset(pScrn, &(pI830->FrontBuffer)); - I830FixOffset(pScrn, pI830->CursorMem); - I830FixOffset(pScrn, pI830->CursorMemARGB); + + for (i = 0; i < xf86_config->num_crtc; i++) { + I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; + + I830FixOffset(pScrn, &intel_crtc->rotate_mem); + I830FixOffset(pScrn, &intel_crtc->cursor_mem); + I830FixOffset(pScrn, &intel_crtc->cursor_mem_argb); + } + I830FixOffset(pScrn, &(pI830->LpRing->mem)); I830FixOffset(pScrn, &(pI830->Scratch)); if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) @@ -1958,6 +2006,9 @@ I830BindAGPMemory(ScrnInfoPtr pScrn) return TRUE; if (xf86AgpGARTSupported() && !pI830->GttBound) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + if (!xf86AcquireGART(pScrn->scrnIndex)) return FALSE; @@ -1973,10 +2024,17 @@ I830BindAGPMemory(ScrnInfoPtr pScrn) return FALSE; if (!BindMemRange(pScrn, &(pI830->FrontBuffer))) return FALSE; - if (!BindMemRange(pScrn, pI830->CursorMem)) - return FALSE; - if (!BindMemRange(pScrn, pI830->CursorMemARGB)) - return FALSE; + + for (i = 0; i < xf86_config->num_crtc; i++) { + I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; + + if (!BindMemRange(pScrn, &intel_crtc->rotate_mem)) + return FALSE; + if (!BindMemRange(pScrn, &intel_crtc->cursor_mem)) + return FALSE; + if (!BindMemRange(pScrn, &intel_crtc->cursor_mem_argb)) + return FALSE; + } if (!BindMemRange(pScrn, &(pI830->LpRing->mem))) return FALSE; if (!BindMemRange(pScrn, &(pI830->Scratch))) @@ -2053,6 +2111,8 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn) return TRUE; if (xf86AgpGARTSupported() && pI830->GttBound) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; #if REMAP_RESERVED /* "unbind" the pre-allocated region. */ @@ -2066,10 +2126,18 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn) return FALSE; if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer))) return FALSE; - if (!UnbindMemRange(pScrn, pI830->CursorMem)) - return FALSE; - if (!UnbindMemRange(pScrn, pI830->CursorMemARGB)) - return FALSE; + + for (i = 0; i < xf86_config->num_crtc; i++) { + I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; + + if (!UnbindMemRange(pScrn, &intel_crtc->rotate_mem)) + return FALSE; + if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem)) + return FALSE; + if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem_argb)) + return FALSE; + } + if (!UnbindMemRange(pScrn, &(pI830->LpRing->mem))) return FALSE; if (!UnbindMemRange(pScrn, &(pI830->Scratch))) |