diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-03-30 09:53:40 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-03-30 09:59:56 -0700 |
commit | 8dabcc40747bfd478f296728741240241698f165 (patch) | |
tree | d02cc6e269765ed29d5636510cb2780b7abc3add | |
parent | 375b2e40fcb17e94538a75392950e2533c1bb031 (diff) |
Tiling fixes, third set
Hopefully this concludes the fixes necessary to deal with the various
combinations of kernel and user level tiling. We have several cases to
handle:
1) KMS (kernel handles all tiling)
2) UMS w/memory management + kexec fencing (kernel handles all tiling)
3) UMS w/memory mangement but no kexec fencing (userland handles tiling)
4) UMS w/o memory management (userland handles tiling)
For cases (1) & (2) we can use GTT mapping, which will give us good
performance and take care of allocating fence registers as needed. It's
important *not* to have userland set up fence regs in this case, since
the kernel will be using all of them.
For case (3), we use the begin/end GTT map functions provided by libdrm,
in combination with pinning and fence register setup in i830_memory.c to
deal with tiled surfaces. This also gives us good performance and
correctness.
For case (4) we use the old style virtual mapping + offset for dealing
with surfaces; note that UXA doesn't seem to work in this configuration
regardless of these fixes.
Fixes bug #20803.
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r-- | src/i830_driver.c | 28 | ||||
-rw-r--r-- | src/i830_exa.c | 44 |
2 files changed, 52 insertions, 20 deletions
diff --git a/src/i830_driver.c b/src/i830_driver.c index 7502d301..d7ee6154 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -823,22 +823,40 @@ i830_update_front_offset(ScrnInfoPtr pScrn) ScreenPtr pScreen = pScrn->pScreen; I830Ptr pI830 = I830PTR(pScrn); int pitch = pScrn->displayWidth * pI830->cpp; + pointer data = NULL; /* Update buffer locations, which may have changed as a result of * i830_bind_all_memory(). */ pScrn->fbOffset = pI830->front_buffer->offset; + if (pI830->starting || pI830->accel == ACCEL_UXA) + return; + /* If we are still in ScreenInit, there is no screen pixmap to be updated * yet. We'll fix it up at CreateScreenResources. */ - if (!pI830->starting && pI830->accel != ACCEL_UXA) { - if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen), + if (!pI830->memory_manager) { + data = pI830->FbBase + pScrn->fbOffset; /* default to legacy */ + } else { + dri_bo *bo = pI830->front_buffer->bo; + + if (bo) { + if (pI830->kernel_exec_fencing) { + if (drm_intel_gem_bo_map_gtt(bo)) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: bo map failed\n", + __FUNCTION__); + } else { + /* Will already be pinned by bind_all_memory in this case */ + drm_intel_gem_bo_start_gtt_access(bo, 1); + } + data = bo->virtual; + } + } + if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen), pScrn->virtualX, pScrn->virtualY, -1, -1, - pitch, (pointer)(pI830->FbBase + - pScrn->fbOffset))) + pitch, data)) FatalError("Couldn't adjust screen pixmap\n"); - } } /** diff --git a/src/i830_exa.c b/src/i830_exa.c index 0a224864..fc4e66ce 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -37,6 +37,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i810_reg.h" #include "i915_drm.h" #include <string.h> +#include <sys/mman.h> #define ALWAYS_SYNC 0 #define ALWAYS_FLUSH 0 @@ -837,8 +838,6 @@ i830_uxa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo) static Bool i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access) { - ScrnInfoPtr pScrn = xf86Screens[pixmap->drawable.pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); dri_bo *bo = i830_get_pixmap_bo (pixmap); if (bo) { @@ -853,16 +852,27 @@ i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access) i830->need_sync = FALSE; } - if (pScrn->vtSema && !pI830->use_drm_mode && pI830->memory_manager) { - if (drm_intel_bo_pin(bo, 4096) != 0) - return FALSE; - drm_intel_gem_bo_start_gtt_access(bo, access == UXA_ACCESS_RW); - pixmap->devPrivate.ptr = pI830->FbBase + bo->offset; - } else { + /* No VT sema or GEM? No GTT mapping. */ + if (!scrn->vtSema || !i830->memory_manager) { if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0) return FALSE; pixmap->devPrivate.ptr = bo->virtual; + return TRUE; + } + + /* Kernel manages fences at GTT map/fault time */ + if (i830->kernel_exec_fencing) { + if (drm_intel_gem_bo_map_gtt(bo)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: bo map failed\n", + __FUNCTION__); + return FALSE; + } + } else { /* or not... */ + if (drm_intel_bo_pin(bo, 4096) != 0) + return FALSE; + drm_intel_gem_bo_start_gtt_access(bo, access == UXA_ACCESS_RW); } + pixmap->devPrivate.ptr = bo->virtual; } return TRUE; } @@ -870,8 +880,6 @@ i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access) static void i830_uxa_finish_access (PixmapPtr pixmap) { - ScrnInfoPtr pScrn = xf86Screens[pixmap->drawable.pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); dri_bo *bo = i830_get_pixmap_bo (pixmap); if (bo) { @@ -879,14 +887,20 @@ i830_uxa_finish_access (PixmapPtr pixmap) ScrnInfoPtr scrn = xf86Screens[screen->myNum]; I830Ptr i830 = I830PTR(scrn); - if (pScrn->vtSema && !pI830->use_drm_mode && pI830->memory_manager) - drm_intel_bo_unpin(bo); - else + if (bo == i830->front_buffer->bo) + i830->need_flush = TRUE; + + if (!scrn->vtSema || !i830->memory_manager) { dri_bo_unmap(bo); + pixmap->devPrivate.ptr = NULL; + return; + } + if (i830->kernel_exec_fencing) + drm_intel_gem_bo_unmap_gtt(bo); + else + drm_intel_bo_unpin(bo); pixmap->devPrivate.ptr = NULL; - if (bo == i830->front_buffer->bo) - i830->need_flush = TRUE; } } |