summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2014-01-15 00:38:39 -0800
committerKenneth Graunke <kenneth@whitecape.org>2014-01-20 10:58:13 -0800
commit02f93c21e6e1c3dad9d99349989daa84a8c0b5fb (patch)
tree58131aeb2eebd1da65624eb96e087aaa99735ab7
parent734de7093db296912da0027e4fa1094f60787c11 (diff)
intel: Track whether a buffer is idle to avoid trips to the kernel.
I've seen a number of apps spending unreasonable amounts of time in drm_intel_bo_busy during the buffer mapping process. We can't track idleness in general, in the case of buffers shared across processes. But this should significantly reduce our overhead for checking for busy on things like VBOs. Improves (unoptimized) glamor x11perf -f8text by 0.243334% +/- 0.161498% (n=1549), which has formerly been spending about .5% of its time hitting the kernel for drm_intel_gem_bo_busy(). Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
-rw-r--r--intel/intel_bufmgr_gem.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index ad722dd5..e20e2c42 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -212,6 +212,15 @@ struct _drm_intel_bo_gem {
bool reusable;
/**
+ * Boolean of whether the GPU is definitely not accessing the buffer.
+ *
+ * This is only valid when reusable, since non-reusable
+ * buffers are those that have been shared wth other
+ * processes, so we don't know their state.
+ */
+ bool idle;
+
+ /**
* Size in bytes of this buffer and its relocation descendents.
*
* Used to avoid costly tree walking in
@@ -567,11 +576,19 @@ drm_intel_gem_bo_busy(drm_intel_bo *bo)
struct drm_i915_gem_busy busy;
int ret;
+ if (bo_gem->reusable && bo_gem->idle)
+ return false;
+
VG_CLEAR(busy);
busy.handle = bo_gem->gem_handle;
ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
-
+ if (ret == 0) {
+ bo_gem->idle = !busy.busy;
+ return busy.busy;
+ } else {
+ return false;
+ }
return (ret == 0 && busy.busy);
}
@@ -2219,6 +2236,8 @@ drm_intel_gem_bo_exec(drm_intel_bo *bo, int used,
drm_intel_bo *bo = bufmgr_gem->exec_bos[i];
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
+ bo_gem->idle = false;
+
/* Disconnect the buffer from the validate list */
bo_gem->validate_index = -1;
bufmgr_gem->exec_bos[i] = NULL;
@@ -2314,6 +2333,8 @@ skip_execution:
drm_intel_bo *bo = bufmgr_gem->exec_bos[i];
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
+ bo_gem->idle = false;
+
/* Disconnect the buffer from the validate list */
bo_gem->validate_index = -1;
bufmgr_gem->exec_bos[i] = NULL;