diff --git a/src/i830.h b/src/i830.h index 661d27e5..f8416dec 100644 --- a/src/i830.h +++ b/src/i830.h @@ -227,8 +227,14 @@ typedef struct _I830CrtcPrivateRec { ExaOffscreenArea *rotate_mem_exa; #endif - i830_memory *cursor_mem; - i830_memory *cursor_mem_argb; + /* Card virtual address of the cursor */ + unsigned long cursor_offset; + unsigned long cursor_argb_offset; + /* Physical or virtual addresses of the cursor for setting in the cursor + * registers. + */ + unsigned long cursor_addr; + unsigned long cursor_argb_addr; Bool cursor_is_argb; } I830CrtcPrivateRec, *I830CrtcPrivatePtr; @@ -276,6 +282,7 @@ typedef struct _I830Rec { i830_memory *front_buffer; i830_memory *front_buffer_2; + i830_memory *cursor_mem; i830_memory *xaa_scratch; i830_memory *xaa_scratch_2; #ifdef I830_USE_EXA diff --git a/src/i830_cursor.c b/src/i830_cursor.c index 9cc92dc9..dec619fe 100644 --- a/src/i830_cursor.c +++ b/src/i830_cursor.c @@ -75,21 +75,14 @@ I830SetPipeCursorBase (xf86CrtcPtr crtc) I830CrtcPrivatePtr intel_crtc = crtc->driver_private; int pipe = intel_crtc->pipe; I830Ptr pI830 = I830PTR(pScrn); - int cursor_base = (pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE); - i830_memory *cursor_mem; - CARD32 value; + int cursor_base; - if (intel_crtc->cursor_is_argb) - cursor_mem = intel_crtc->cursor_mem_argb; - else - cursor_mem = intel_crtc->cursor_mem; - - if (pI830->CursorNeedsPhysical) - value = cursor_mem->bus_addr; - else - value = cursor_mem->offset; + cursor_base = (pipe == 0) ? CURSOR_A_BASE : CURSOR_B_BASE; - OUTREG(cursor_base, value); + if (intel_crtc->cursor_is_argb) + OUTREG(cursor_base, intel_crtc->cursor_argb_addr); + else + OUTREG(cursor_base, intel_crtc->cursor_addr); } void @@ -143,11 +136,11 @@ I830CursorInit(ScreenPtr pScreen) void i830_crtc_load_cursor_image (xf86CrtcPtr crtc, unsigned char *src) { - ScrnInfoPtr scrn = crtc->scrn; - I830Ptr pI830 = I830PTR(scrn); + I830Ptr pI830 = I830PTR(crtc->scrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - CARD8 *pcurs = (CARD8 *) (pI830->FbBase + - intel_crtc->cursor_mem->offset); + CARD8 *pcurs; + + pcurs = pI830->FbBase + intel_crtc->cursor_offset; intel_crtc->cursor_is_argb = FALSE; memcpy (pcurs, src, I810_CURSOR_X * I810_CURSOR_Y / 4); @@ -157,11 +150,11 @@ i830_crtc_load_cursor_image (xf86CrtcPtr crtc, unsigned char *src) void i830_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) { - ScrnInfoPtr scrn = crtc->scrn; - I830Ptr pI830 = I830PTR(scrn); + I830Ptr pI830 = I830PTR(crtc->scrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - CARD32 *pcurs = (CARD32 *) (pI830->FbBase + - intel_crtc->cursor_mem_argb->offset); + CARD32 *pcurs; + + pcurs = pI830->FbBase + intel_crtc->cursor_argb_offset; intel_crtc->cursor_is_argb = TRUE; memcpy (pcurs, image, I810_CURSOR_Y * I810_CURSOR_X * 4); diff --git a/src/i830_memory.c b/src/i830_memory.c index a20e7432..440618a5 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -62,10 +62,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * The allocations we might do: * * - Ring buffer - * - HW cursor 1 - * - HW cursor 2 - * - HW ARGB cursor 1 - * - HW ARGB cursor 2 + * - HW cursor block * - Overlay registers * - XAA linear allocator (optional) * - EXA 965 state buffer @@ -214,8 +211,6 @@ void i830_reset_allocations(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; /* While there is any memory between the start and end markers, free it. */ while (pI830->memory_list->next->next != NULL) @@ -224,13 +219,7 @@ i830_reset_allocations(ScrnInfoPtr pScrn) /* Null out the pointers for all the allocations we just freed. This is * kind of gross, but at least it's just one place now. */ - for (i = 0; i < xf86_config->num_crtc; i++) { - I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; - - intel_crtc->cursor_mem = NULL; - intel_crtc->cursor_mem_argb = NULL; - } - + pI830->cursor_mem = NULL; pI830->front_buffer = NULL; pI830->front_buffer_2 = NULL; pI830->xaa_scratch = NULL; @@ -849,51 +838,51 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, } static Bool -i830_allocate_cursor_buffers(xf86CrtcPtr crtc) +i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) { - ScrnInfoPtr pScrn = crtc->scrn; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; I830Ptr pI830 = I830PTR(pScrn); - long size; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; + int i; + long size; - 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. + /* Try to allocate one big blob for our cursor memory. This works + * around a limitation in the FreeBSD AGP driver that allows only one + * physical allocation larger than a page, and could allos us + * to pack the cursors smaller. */ + size = xf86_config->num_crtc * (HWCURSOR_SIZE + HWCURSOR_SIZE_ARGB); - size = HWCURSOR_SIZE; + pI830->cursor_mem = i830_allocate_memory(pScrn, "HW cursors", + size, GTT_PAGE_SIZE, + flags); + if (pI830->cursor_mem != NULL) { + unsigned long cursor_offset_base = pI830->cursor_mem->offset; + unsigned long cursor_addr_base, offset = 0; - if (intel_crtc->cursor_mem == NULL) { - intel_crtc->cursor_mem = i830_allocate_memory(pScrn, "HW cursor", - size, GTT_PAGE_SIZE, - flags); - if (intel_crtc->cursor_mem == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW cursor space.\n"); - return FALSE; + if (pI830->CursorNeedsPhysical) + cursor_addr_base = pI830->cursor_mem->bus_addr; + else + cursor_addr_base = pI830->cursor_mem->offset; + + /* Set up the offsets for our cursors in each CRTC. */ + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + intel_crtc->cursor_argb_addr = cursor_addr_base + offset; + intel_crtc->cursor_argb_offset = cursor_offset_base + offset; + offset += HWCURSOR_SIZE_ARGB; + + intel_crtc->cursor_addr = cursor_addr_base + offset; + intel_crtc->cursor_offset = cursor_offset_base + offset; + offset += HWCURSOR_SIZE; } + + return TRUE; } - if (intel_crtc->cursor_mem_argb == NULL) { - /* Allocate the ARGB cursor space. Its success is optional -- we won't - * set SWCursor if it fails. - */ - intel_crtc->cursor_mem_argb = i830_allocate_memory(pScrn, - "HW ARGB cursor", - HWCURSOR_SIZE_ARGB, - GTT_PAGE_SIZE, - flags); - if (intel_crtc->cursor_mem_argb == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW (ARGB) cursor space.\n"); - } - } - - return TRUE; + return FALSE; } /* @@ -904,10 +893,8 @@ Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); unsigned int pitch = pScrn->displayWidth * pI830->cpp; long size; - int i; if (!pI830->StolenOnly && (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { @@ -923,19 +910,11 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) i830_allocate_ringbuffer(pScrn); /* Next, allocate other fixed-size allocations we have. */ - if (!pI830->SWCursor) { - /* Allocate cursor memory */ - for (i = 0; i < xf86_config->num_crtc; i++) { - if (!i830_allocate_cursor_buffers(xf86_config->crtc[i]) && - !pI830->SWCursor) - { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Disabling HW cursor because the cursor memory " - "allocation failed.\n"); - pI830->SWCursor = TRUE; - break; - } - } + if (!pI830->SWCursor && !i830_allocate_cursor_buffers(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Disabling HW cursor because the cursor memory " + "allocation failed.\n"); + pI830->SWCursor = TRUE; } /* Space for the X Server's 3D context. 32k is fine for right now. */