diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-12-16 23:04:55 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-12-16 23:04:55 +0000 |
commit | 5b0572503eab235bc7eff20d369241330c41e630 (patch) | |
tree | 2ff5b23d0f961a56e8dce8b1734db9226ba106c4 | |
parent | 805f78addf3ffb36c736df680806cf722b18fea9 (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.ac | 9 | ||||
-rw-r--r-- | src/sna/kgem.c | 35 | ||||
-rw-r--r-- | src/sna/kgem.h | 1 |
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; |