diff options
-rw-r--r-- | src/i830_accel.c | 33 | ||||
-rw-r--r-- | src/i830_batchbuffer.c | 2 | ||||
-rw-r--r-- | src/i830_dri.c | 63 | ||||
-rw-r--r-- | src/i830_driver.c | 49 | ||||
-rw-r--r-- | src/i830_memory.c | 8 |
5 files changed, 104 insertions, 51 deletions
diff --git a/src/i830_accel.c b/src/i830_accel.c index a71ea475..c3cd08e0 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -54,12 +54,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ +#include <errno.h> + #include "xf86.h" #include "xaarop.h" #include "i830.h" #include "i810_reg.h" #include "i830_debug.h" #include "i830_ring.h" +#include "i915_drm.h" unsigned long intel_get_pixmap_offset(PixmapPtr pPix) @@ -190,7 +193,35 @@ I830Sync(ScrnInfoPtr pScrn) intel_batch_flush(pScrn); - i830_wait_ring_idle(pScrn); + if (pI830->directRenderingEnabled) { + struct drm_i915_irq_emit emit; + struct drm_i915_irq_wait wait; + int ret; + + /* Most of the uses of I830Sync while using GEM should actually be + * using set_domain on a specific buffer. We're not there yet, so fake + * it up using irq_emit/wait. It's still better than spinning on + * register reads for idle. + */ + emit.irq_seq = &wait.irq_seq; + ret = drmCommandWrite(pI830->drmSubFD, DRM_I830_IRQ_EMIT, &emit, + sizeof(emit)); + if (ret != 0) + FatalError("Failure to emit IRQ: %s\n", strerror(-ret)); + + do { + ret = drmCommandWrite(pI830->drmSubFD, DRM_I830_IRQ_WAIT, &wait, + sizeof(wait)); + } while (ret == -EINTR); + + if (ret != 0) + FatalError("Failure to wait for IRQ: %s\n", strerror(-ret)); + + if (!pI830->memory_manager) + i830_refresh_ring(pScrn); + } else { + i830_wait_ring_idle(pScrn); + } pI830->nextColorExpandBuf = 0; } diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c index 416f4d05..2f53d2ff 100644 --- a/src/i830_batchbuffer.c +++ b/src/i830_batchbuffer.c @@ -115,8 +115,6 @@ intel_batch_flush(ScrnInfoPtr pScrn) exec, sizeof(*exec)); if (ret != 0) FatalError("Failed to submit batchbuffer: %s\n", strerror(errno)); - - i830_refresh_ring(pScrn); } else { dri_process_relocs(pI830->batch_bo); diff --git a/src/i830_dri.c b/src/i830_dri.c index 8ec51fcc..5a536706 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -175,22 +175,31 @@ I830InitDma(ScrnInfoPtr pScrn) memset(&info, 0, sizeof(drmI830Init)); info.func = I830_INIT_DMA; - info.ring_start = ring->mem->offset + pI830->LinearAddr; - info.ring_end = ring->mem->end + pI830->LinearAddr; - info.ring_size = ring->mem->size; + /* Initialize fields that are used in the absence of GEM */ + if (!pI830->memory_manager) { + info.ring_start = ring->mem->offset + pI830->LinearAddr; + info.ring_end = ring->mem->end + pI830->LinearAddr; + info.ring_size = ring->mem->size; + + /* Not used as of the middle of GEM development. */ + info.mmio_offset = (unsigned int)pI830DRI->regs; + + /* Not used as of before GEM development */ + info.front_offset = pI830->front_buffer->offset; + info.back_offset = pI830->back_buffer->offset; + info.depth_offset = pI830->depth_buffer->offset; + info.pitch = pScrn->displayWidth; + info.back_pitch = pScrn->displayWidth; + info.depth_pitch = pScrn->displayWidth; + info.w = pScrn->virtualX; + info.h = pScrn->virtualY; + } - info.mmio_offset = (unsigned int)pI830DRI->regs; info.sarea_priv_offset = sizeof(XF86DRISAREARec); - info.front_offset = pI830->front_buffer->offset; - info.back_offset = pI830->back_buffer->offset; - info.depth_offset = pI830->depth_buffer->offset; - info.w = pScrn->virtualX; - info.h = pScrn->virtualY; - info.pitch = pScrn->displayWidth; - info.back_pitch = pScrn->displayWidth; - info.depth_pitch = pScrn->displayWidth; + /* This should probably have been moved alongside offset/pitch in the sarea. + */ info.cpp = pI830->cpp; if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT, @@ -799,17 +808,20 @@ I830DRIDoMappings(ScreenPtr pScreen) xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n", (int)pI830DRI->regs); - if (drmAddMap(pI830->drmSubFD, - (drm_handle_t)pI830->LpRing->mem->offset + pI830->LinearAddr, - pI830->LpRing->mem->size, DRM_AGP, 0, - (drmAddress) &pI830->ring_map) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); - DRICloseScreen(pScreen); - return FALSE; + if (!pI830->memory_manager) { + if (drmAddMap(pI830->drmSubFD, + (drm_handle_t)pI830->LpRing->mem->offset + + pI830->LinearAddr, + pI830->LpRing->mem->size, DRM_AGP, 0, + (drmAddress) &pI830->ring_map) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] ring buffer = 0x%08x\n", + (int)pI830->ring_map); } - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] ring buffer = 0x%08x\n", - (int)pI830->ring_map); if (!I830InitDma(pScrn)) { DRICloseScreen(pScreen); @@ -960,6 +972,7 @@ I830DRICloseScreen(ScreenPtr pScreen) xfree(pI830->pVisualConfigs); if (pI830->pVisualConfigsPriv) xfree(pI830->pVisualConfigsPriv); + pI830->directRenderingEnabled = FALSE; } static Bool @@ -1065,7 +1078,8 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, if (!pScrn->vtSema) return; pI830->LockHeld = 1; - i830_refresh_ring(pScrn); + if (!pI830->memory_manager) + i830_refresh_ring(pScrn); #ifdef DAMAGE if (!pI830->pDamage && pI830->allowPageFlip) { @@ -1763,7 +1777,8 @@ I830DRILock(ScrnInfoPtr pScrn) if (pI830->directRenderingEnabled && !pI830->LockHeld) { DRILock(screenInfo.screens[pScrn->scrnIndex], 0); pI830->LockHeld = 1; - i830_refresh_ring(pScrn); + if (!pI830->memory_manager) + i830_refresh_ring(pScrn); return TRUE; } else diff --git a/src/i830_driver.c b/src/i830_driver.c index bce00af1..e7994df6 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -211,6 +211,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include <sys/ioctl.h> #ifdef XF86DRI_MM #include "xf86mm.h" +#include "i915_drm.h" #endif #endif @@ -3005,7 +3006,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif if (!pI830->noAccel) { - if (pI830->LpRing->mem->size == 0) { + if (pI830->memory_manager == NULL && pI830->LpRing->mem->size == 0) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling acceleration because the ring buffer " "allocation failed.\n"); @@ -3357,7 +3358,8 @@ I830LeaveVT(int scrnIndex, int flags) intel_bufmgr_fake_evict_all(pI830->bufmgr); intel_batch_teardown(pScrn); - i830_stop_ring(pScrn, TRUE); + if (!pI830->memory_manager) + i830_stop_ring(pScrn, TRUE); if (pI830->debug_modes) { i830CompareRegsToSnapshot(pScrn, "After LeaveVT"); @@ -3367,15 +3369,16 @@ I830LeaveVT(int scrnIndex, int flags) if (I830IsPrimary(pScrn)) i830_unbind_all_memory(pScrn); - /* Tell the kernel to evict all buffer objects and block new buffer - * allocations until we relese the lock. - */ #ifdef XF86DRI_MM - if (pI830->directRenderingOpen) { - /* XXX: - if (pI830->memory_manager != NULL && pScrn->vtSema) { - drmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT, 1, 0); - }*/ + if (pI830->memory_manager) { + int ret; + + /* Tell the kernel to evict all buffer objects and block GTT usage while + * we're no longer in control of the chip. + */ + ret = drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_LEAVEVT); + if (ret != 0) + FatalError("DRM_I915_LEAVEVT failed: %s\n", strerror(ret)); } #endif /* XF86DRI_MM */ @@ -3409,15 +3412,15 @@ I830EnterVT(int scrnIndex, int flags) pI830->leaving = FALSE; #ifdef XF86DRI_MM - if (pI830->directRenderingEnabled) { - /* Unlock the memory manager first of all so that we can pin our - * buffer objects + if (pI830->memory_manager) { + int ret; + + /* Tell the kernel that we're back in control and ready for GTT + * usage. */ - /* - if (pI830->memory_manager != NULL && pScrn->vtSema) { - drmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT, 1); - } - */ + ret = drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_ENTERVT); + if (ret != 0) + FatalError("DRM_I915_ENTERVT failed: %s\n", strerror(ret)); } #endif /* XF86DRI_MM */ @@ -3440,8 +3443,11 @@ I830EnterVT(int scrnIndex, int flags) "Existing errors found in hardware state.\n"); } - i830_stop_ring(pScrn, FALSE); - i830_start_ring(pScrn); + /* Re-set up the ring. */ + if (!pI830->memory_manager) { + i830_stop_ring(pScrn, FALSE); + i830_start_ring(pScrn); + } if (!pI830->SWCursor) I830InitHWCursor(pScrn); @@ -3504,7 +3510,8 @@ I830EnterVT(int scrnIndex, int flags) I830DRIResume(screenInfo.screens[scrnIndex]); - i830_refresh_ring(pScrn); + if (!pI830->memory_manager) + i830_refresh_ring(pScrn); I830Sync(pScrn); sarea->texAge++; diff --git a/src/i830_memory.c b/src/i830_memory.c index db99d97e..36131672 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -996,7 +996,7 @@ i830_allocate_ringbuffer(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - if (pI830->noAccel || pI830->LpRing->mem != NULL) + if (pI830->noAccel || pI830->memory_manager || pI830->LpRing->mem != NULL) return TRUE; /* We don't have any mechanism in the DRM yet to alert it that we've moved @@ -1632,8 +1632,10 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn) size / 1024); return FALSE; } - /* The offset must stay constant currently because we don't ever update - * the DRI maps after screen init. + /* Now that the DRM uses the sarea to get the offsets of the buffers, + * and we update the classic DRM mappings and the sarea contents on + * changes, the NEED_LIFETIME_FIXED is no longer true and should be + * made conditional on DRM version. */ pI830->textures = i830_allocate_memory(pScrn, "classic textures", size, GTT_PAGE_SIZE, |