diff --git a/src/i830.h b/src/i830.h index ee0f03a..33ac2ef 100644 --- a/src/i830.h +++ b/src/i830.h @@ -412,6 +412,7 @@ typedef struct _I830Rec { CreateScreenResourcesProcPtr CreateScreenResources; i830_memory *logical_context; + i830_memory *other_context; #ifdef XF86DRI i830_memory *back_buffer; diff --git a/src/i830_driver.c b/src/i830_driver.c index e1ab536..510523d 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2047,6 +2047,8 @@ RestoreHWState(ScrnInfoPtr pScrn) DPRINTF(PFX, "RestoreHWState\n"); + i830_restore_context(pScrn); + #ifdef XF86DRI I830DRISetVBlankInterrupt (pScrn, FALSE); #endif @@ -2306,6 +2308,23 @@ I830InitFBManager( return ret; } +void +i830_restore_context(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (pI830->noAccel) + return; + + /* Switch back to "other" context */ + { + BEGIN_BATCH(2); + OUT_BATCH(MI_SET_CONTEXT); + OUT_BATCH(pI830->other_context->offset); + ADVANCE_BATCH(); + } +} + /** * Intialiazes the hardware for the 3D pipeline use in the 2D driver. * @@ -2338,14 +2357,24 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn) if (*pI830->last_3d != LAST_3D_OTHER) return; + /* Install "other" pointer so subsequent switch will save last state */ + { + BEGIN_BATCH(2); + OUT_BATCH(MI_SET_CONTEXT); + OUT_BATCH(pI830->other_context->offset | + CTXT_NO_RESTORE | + CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE); + ADVANCE_BATCH(); + } + + /* Setup fresh context */ ctx_addr = pI830->logical_context->offset; assert((pI830->logical_context->offset & 2047) == 0); { BEGIN_BATCH(2); OUT_BATCH(MI_SET_CONTEXT); OUT_BATCH(pI830->logical_context->offset | - CTXT_NO_RESTORE | - CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE); + CTXT_NO_RESTORE | CTXT_PALETTE_RESTORE_DISABLE); ADVANCE_BATCH(); } diff --git a/src/i830_memory.c b/src/i830_memory.c index 2cac26b..074b3cc 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1383,6 +1383,15 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) return FALSE; } + /* Space for "other" 3D context. */ + pI830->other_context = i830_allocate_memory(pScrn, "other 3D context", + KB(32), GTT_PAGE_SIZE, 0); + if (pI830->other_context == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate other context space.\n"); + return FALSE; + } + /* even in XAA, 965G needs state mem buffer for rendering */ if (IS_I965G(pI830) && !pI830->noAccel && pI830->exa_965_state == NULL) { pI830->exa_965_state =