xf86-video-intel: 2 commits - src/drmmode_display.c src/i830_exa.c src/i830.h src/i830_memory.c src/i830_video.c
Eric Anholt
anholt at kemper.freedesktop.org
Tue May 19 10:09:52 PDT 2009
src/drmmode_display.c | 2 ++
src/i830.h | 2 ++
src/i830_exa.c | 20 ++++++++++++++++----
src/i830_memory.c | 26 ++++++++++++++++++++++++++
src/i830_video.c | 16 +++++++++-------
5 files changed, 55 insertions(+), 11 deletions(-)
New commits:
commit 09beee378cecd1079e7a9fa6eee8f084d680d37e
Author: Eric Anholt <eric at anholt.net>
Date: Mon May 18 18:01:05 2009 -0700
Don't do GTT maps on objects bigger than half the available aperture size.
The basic problem is that software fallbacks will do single instructions that
copy from one GTT-mapped BO into another GTT-mapped BO. If we can't get both
of them bound simultanously, we fault one in, retry the instruction, fault the
other in (kicking out #1), retry the instruction, fault #1 back in
(kicking out #2), etc.
Note that we'll still get into a nasty spot if you do a composite operation
with a mask where all 3 are big-but-less-than-half-available-aperture, where
you'll thrash. It at least means you'll make progress, though, since each
instruction will only be operating on two BOs at at time, and the situation
seems unlikely.
Bug #20152 (3/3)
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 7df7b6f..24e0e26 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -232,6 +232,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
drmmode_output_dpms(output, DPMSModeOn);
}
+ i830_set_max_gtt_map_size(pScrn);
+
done:
if (!ret) {
crtc->x = saved_x;
diff --git a/src/i830.h b/src/i830.h
index 0969c48..7c260de 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -437,6 +437,7 @@ typedef struct _I830Rec {
int accel_pixmap_offset_alignment;
int accel_max_x;
int accel_max_y;
+ int max_gtt_map_size;
I830WriteIndexedByteFunc writeControl;
I830ReadIndexedByteFunc readControl;
@@ -748,6 +749,7 @@ Bool i830_bind_all_memory(ScrnInfoPtr pScrn);
Bool i830_unbind_all_memory(ScrnInfoPtr pScrn);
unsigned long i830_get_fence_size(I830Ptr pI830, unsigned long size);
unsigned long i830_get_fence_pitch(I830Ptr pI830, unsigned long pitch, int format);
+void i830_set_max_gtt_map_size(ScrnInfoPtr pScrn);
Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 824f032..3ca7933 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -506,9 +506,18 @@ i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
/* 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__);
+ if (bo->size < i830->max_gtt_map_size) {
+ if (drm_intel_gem_bo_map_gtt(bo)) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "%s: bo map failed\n",
+ __FUNCTION__);
+ return FALSE;
+ }
+ } else {
+ if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0)
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "%s: bo map failed\n",
+ __FUNCTION__);
return FALSE;
}
pixmap->devPrivate.ptr = bo->virtual;
@@ -542,7 +551,10 @@ i830_uxa_finish_access (PixmapPtr pixmap)
}
if (i830->kernel_exec_fencing)
- drm_intel_gem_bo_unmap_gtt(bo);
+ if (bo->size < i830->max_gtt_map_size)
+ drm_intel_gem_bo_unmap_gtt(bo);
+ else
+ dri_bo_unmap(bo);
else
drm_intel_bo_unpin(bo);
pixmap->devPrivate.ptr = NULL;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 2a697a7..99b9fc8 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1128,6 +1128,8 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn)
if (!pI830->use_drm_mode && pI830->FbBase && front_buffer->bound)
memset (pI830->FbBase + front_buffer->offset, 0, size);
+ i830_set_max_gtt_map_size(pScrn);
+
return front_buffer;
}
@@ -1588,6 +1590,7 @@ i830_bind_all_memory(ScrnInfoPtr pScrn)
}
if (!pI830->use_drm_mode)
i830_update_cursor_offsets(pScrn);
+ i830_set_max_gtt_map_size(pScrn);
return TRUE;
}
@@ -1672,3 +1675,26 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
return TRUE;
}
#endif
+
+void
+i830_set_max_gtt_map_size(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ struct drm_i915_gem_get_aperture aperture;
+ int ret;
+
+ /* Default low value in case it gets used during server init. */
+ pI830->max_gtt_map_size = 16 * 1024 * 1024;
+
+ if (!pI830->have_gem)
+ return;
+
+ ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
+ if (ret == 0) {
+ /* Let objects up get bound up to the size where only 2 would fit in
+ * the aperture, but then leave slop to account for alignment like
+ * libdrm does.
+ */
+ pI830->max_gtt_map_size = aperture.aper_available_size * 3 / 4 / 2;
+ }
+}
commit 34660fd2df5d61b77ed7041d32ac29053fc94f5a
Author: Eric Anholt <eric at anholt.net>
Date: Fri May 15 23:21:05 2009 -0700
Only sync XV to vblank when drawing to the frontbuffer.
This fixes emitting syncs to random pipes with boxes bigger than that
pipe's vertical, leading to GPU hangs.
Bug #21738
diff --git a/src/i830_video.c b/src/i830_video.c
index 1c3a5b7..6fec8ff 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2495,13 +2495,15 @@ I830PutImage(ScrnInfoPtr pScrn,
if (sync) {
BoxPtr box;
int y1, y2;
- int pipe, event, load_scan_lines_pipe;
-
- if (pI830->use_drm_mode)
- pipe = drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc);
- else {
- I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
- pipe = intel_crtc->pipe;
+ int pipe = -1, event, load_scan_lines_pipe;
+
+ if (pPixmap != pScreen->GetScreenPixmap(pScreen)) {
+ if (pI830->use_drm_mode)
+ pipe = drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc);
+ else {
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ pipe = intel_crtc->pipe;
+ }
}
if (pipe >= 0) {
More information about the xorg-commit
mailing list