summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2009-03-30 09:53:40 -0700
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-03-30 09:59:56 -0700
commit8dabcc40747bfd478f296728741240241698f165 (patch)
treed02cc6e269765ed29d5636510cb2780b7abc3add
parent375b2e40fcb17e94538a75392950e2533c1bb031 (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.c28
-rw-r--r--src/i830_exa.c44
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;
}
}