summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-12-16 23:04:55 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-12-16 23:04:55 +0000
commit5b0572503eab235bc7eff20d369241330c41e630 (patch)
tree2ff5b23d0f961a56e8dce8b1734db9226ba106c4
parent805f78addf3ffb36c736df680806cf722b18fea9 (diff)
sna: Enable support for opting out of the kernel CS workaround
Keeping a set of pinned batches in userspace is considerably faster as we can avoid the blit overhead. However, combining the two approaches yields even greater performance, as fast as without either w/a, and yet stable. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--configure.ac9
-rw-r--r--src/sna/kgem.c35
-rw-r--r--src/sna/kgem.h1
3 files changed, 38 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac
index 93544372..e1530195 100644
--- a/configure.ac
+++ b/configure.ac
@@ -282,6 +282,15 @@ if test "x$accel" = xnone -a "x$UMS_ONLY" != "xyes"; then
AC_MSG_ERROR([No default acceleration option])
fi
+AC_ARG_ENABLE(pinned-batches,
+ AS_HELP_STRING([--enable-pinned-batches],
+ [Enable use of "pinned batches" (experimental) [default=no]]),
+ [PINNED="$enableval"],
+ [PINNED=no])
+if test "x$PINNED" = xyes; then
+ AC_DEFINE(USE_PINNED_BATCHES,1,[Assume "pinned batches" support])
+fi
+
AC_ARG_ENABLE(userptr,
AS_HELP_STRING([--enable-userptr],
[Enable use of userptr (experimental) [default=no]]),
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 36eab9bd..ad967ebf 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -70,12 +70,18 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
#define DBG_NO_MAP_UPLOAD 0
#define DBG_NO_RELAXED_FENCING 0
#define DBG_NO_SECURE_BATCHES 0
+#define DBG_NO_PINNED_BATCHES 0
#define DBG_NO_FAST_RELOC 0
#define DBG_NO_HANDLE_LUT 0
#define DBG_DUMP 0
#define SHOW_BATCH 0
+#ifndef USE_PINNED_BATCHES
+#undef DBG_NO_PINNED_BATCHES
+#define DBG_NO_PINNED_BATCHES 1
+#endif
+
#ifndef USE_FASTRELOC
#undef DBG_NO_FAST_RELOC
#define DBG_NO_FAST_RELOC 1
@@ -110,11 +116,13 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
#define LOCAL_I915_PARAM_HAS_SEMAPHORES 20
#define LOCAL_I915_PARAM_HAS_SECURE_BATCHES 23
-#define LOCAL_I915_PARAM_HAS_NO_RELOC 24
-#define LOCAL_I915_PARAM_HAS_HANDLE_LUT 25
+#define LOCAL_I915_PARAM_HAS_PINNED_BATCHES 24
+#define LOCAL_I915_PARAM_HAS_NO_RELOC 25
+#define LOCAL_I915_PARAM_HAS_HANDLE_LUT 26
-#define LOCAL_I915_EXEC_NO_RELOC (1<<10)
-#define LOCAL_I915_EXEC_HANDLE_LUT (1<<11)
+#define LOCAL_I915_EXEC_IS_PINNED (1<<10)
+#define LOCAL_I915_EXEC_NO_RELOC (1<<11)
+#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
#define LOCAL_I915_GEM_USERPTR 0x32
#define LOCAL_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_USERPTR, struct local_i915_gem_userptr)
@@ -828,6 +836,14 @@ static bool test_has_secure_batches(struct kgem *kgem)
return gem_param(kgem, LOCAL_I915_PARAM_HAS_SECURE_BATCHES) > 0;
}
+static bool test_has_pinned_batches(struct kgem *kgem)
+{
+ if (DBG_NO_PINNED_BATCHES)
+ return false;
+
+ return gem_param(kgem, LOCAL_I915_PARAM_HAS_PINNED_BATCHES) > 0;
+}
+
static int kgem_get_screen_index(struct kgem *kgem)
{
struct sna *sna = container_of(kgem, struct sna, kgem);
@@ -943,7 +959,6 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
kgem->vma[MAP_GTT].count = -MAX_GTT_VMA_CACHE;
kgem->vma[MAP_CPU].count = -MAX_CPU_VMA_CACHE;
-
kgem->has_blt = gem_param(kgem, I915_PARAM_HAS_BLT) > 0;
DBG(("%s: has BLT ring? %d\n", __FUNCTION__,
kgem->has_blt));
@@ -991,6 +1006,10 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
DBG(("%s: can use privileged batchbuffers? %d\n", __FUNCTION__,
kgem->has_secure_batches));
+ kgem->has_pinned_batches = test_has_pinned_batches(kgem);
+ DBG(("%s: can use pinned batchbuffers (to avoid CS w/a)? %d\n", __FUNCTION__,
+ kgem->has_pinned_batches));
+
if (!is_hw_supported(kgem, dev)) {
xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING,
"Detected unsupported/dysfunctional hardware, disabling acceleration.\n");
@@ -1002,7 +1021,7 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
}
kgem->batch_size = ARRAY_SIZE(kgem->batch);
- if (gen == 020)
+ if (gen == 020 && !kgem->has_pinned_batches)
/* Limited to what we can pin */
kgem->batch_size = 4*1024;
if (gen == 022)
@@ -1144,6 +1163,8 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
kgem->batch_flags_base |= LOCAL_I915_EXEC_NO_RELOC;
if (kgem->has_handle_lut)
kgem->batch_flags_base |= LOCAL_I915_EXEC_HANDLE_LUT;
+ if (kgem->has_pinned_batches)
+ kgem->batch_flags_base |= LOCAL_I915_EXEC_IS_PINNED;
}
/* XXX hopefully a good approximation */
@@ -2395,7 +2416,7 @@ out_16384:
}
}
- if (kgem->gen == 020) {
+ if (kgem->gen == 020 && !kgem->has_pinned_batches) {
assert(size <= 16384);
bo = list_first_entry(&kgem->pinned_batches[size > 4096],
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 59be858b..c23b9e33 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -170,6 +170,7 @@ struct kgem {
uint32_t has_relaxed_delta :1;
uint32_t has_semaphores :1;
uint32_t has_secure_batches :1;
+ uint32_t has_pinned_batches :1;
uint32_t has_cacheing :1;
uint32_t has_llc :1;
uint32_t has_no_reloc :1;