Fix crashes and other failures when a cursor allocation fails.
Now, we allocate one single block of memory for cursors, and either succeed or fail once, rather than trying to support partial fallback modes that generally resulted in pain due to being untested. In particular, this fixes cursors on FreeBSD, which only allowed one large physically-contiguous allocation.
This commit is contained in:
parent
316ee682d3
commit
213394fbaa
11
src/i830.h
11
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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue