summaryrefslogtreecommitdiff
path: root/src/i830_memory.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-05-18 18:01:05 -0700
committerEric Anholt <eric@anholt.net>2009-05-19 10:09:41 -0700
commit09beee378cecd1079e7a9fa6eee8f084d680d37e (patch)
tree079c53d1e96e60e89f496bd98871145dbfb84e8f /src/i830_memory.c
parent34660fd2df5d61b77ed7041d32ac29053fc94f5a (diff)
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)
Diffstat (limited to 'src/i830_memory.c')
-rw-r--r--src/i830_memory.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 2a697a7d..99b9fc85 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;
+ }
+}