summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2009-03-30 09:53:40 -0700
committerCarl Worth <cworth@cworth.org>2009-03-31 17:06:31 -0700
commitf6f59ee2533e786906dc9a32cf7072f2d2796201 (patch)
tree85551ad65df50b21861fd4a18341903c7b5d813c
parenta03feab1b7ce511e1704bee96c83290d1c7b2785 (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> (cherry picked from commit 8dabcc40747bfd478f296728741240241698f165)
-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;
}
}