summaryrefslogtreecommitdiff
path: root/src/i830_memory.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2007-01-18 14:26:21 -0800
committerEric Anholt <eric@anholt.net>2007-01-18 14:26:21 -0800
commit74ebff6732b9bfcf8c865b52cbebfd9bf6b73eb2 (patch)
tree2b947b57dd9ea8d3e61a1c43455c0fd6b216b6f9 /src/i830_memory.c
parent8759f4d89a141f7d69f1894ec3059ba6bd1cf86b (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.c206
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)))