summaryrefslogtreecommitdiff
path: root/src/sna/kgem.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-09-11 21:48:24 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-09-21 11:56:16 +0100
commit0be1d964713ca407f029278a8256d02d925dc9da (patch)
treed360eb12a9eed2b0938df9a5c5475da2bf82c1b2 /src/sna/kgem.c
parentd853064e7eebc5719645c12605782f995131a6fe (diff)
sna: Use inplace X tiling for LLC uploads
Based on a suggestion by Chad Versace (taken from a patch for mesa). This allows for a faster upload of pixel data through a ShmImage, or for complete replacement of a GPU bo. Using a modified version of x11perf to upload to a pixmap rather than scanout on an IVB i7-3720qm: Before: 40000000 trep @ 0.0007 msec (1410000.0/sec): ShmPutImage 10x10 square 4000000 trep @ 0.0110 msec ( 90700.0/sec): ShmPutImage 100x100 square 160000 trep @ 0.1689 msec ( 5920.0/sec): ShmPutImage 500x500 square After: 40000000 trep @ 0.0007 msec (1450000.0/sec): ShmPutImage 10x10 square 6000000 trep @ 0.0061 msec ( 164000.0/sec): ShmPutImage 100x100 square 400000 trep @ 0.1126 msec ( 8880.0/sec): ShmPutImage 500x500 square However, the real takeaway from this is that the overheads for ShmPutImage are substantial, only hitting around 70% expected efficiency, and overshadowed by PutImage, which for reference is 60000000 trep @ 0.0006 msec (1800000.0/sec): PutImage 10x10 square Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/kgem.c')
-rw-r--r--src/sna/kgem.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index fc7c8811..0ea14f01 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -4082,6 +4082,56 @@ retry:
return (void *)(uintptr_t)mmap_arg.addr_ptr;
}
+void *__kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
+{
+ struct drm_i915_gem_mmap mmap_arg;
+
+ DBG(("%s(handle=%d, size=%d, mapped? %d)\n",
+ __FUNCTION__, bo->handle, bytes(bo), (int)__MAP_TYPE(bo->map)));
+ assert(bo->refcnt);
+ assert(!bo->purged);
+ assert(list_is_empty(&bo->list));
+ assert(bo->proxy == NULL);
+
+ if (IS_CPU_MAP(bo->map))
+ return MAP(bo->map);
+
+retry:
+ VG_CLEAR(mmap_arg);
+ mmap_arg.handle = bo->handle;
+ mmap_arg.offset = 0;
+ mmap_arg.size = bytes(bo);
+ if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg)) {
+ ErrorF("%s: failed to mmap %d, %d bytes, into CPU domain: %d\n",
+ __FUNCTION__, bo->handle, bytes(bo), errno);
+ if (__kgem_throttle_retire(kgem, 0))
+ goto retry;
+
+ return NULL;
+ }
+
+ VG(VALGRIND_MAKE_MEM_DEFINED(mmap_arg.addr_ptr, bytes(bo)));
+ if (bo->map == NULL) {
+ DBG(("%s: caching CPU vma for %d\n", __FUNCTION__, bo->handle));
+ bo->map = MAKE_CPU_MAP(mmap_arg.addr_ptr);
+ }
+ return (void *)(uintptr_t)mmap_arg.addr_ptr;
+}
+
+void __kgem_bo_unmap__cpu(struct kgem *kgem, struct kgem_bo *bo, void *ptr)
+{
+ DBG(("%s(handle=%d, size=%d)\n",
+ __FUNCTION__, bo->handle, bytes(bo)));
+ assert(bo->refcnt);
+
+ if (IS_CPU_MAP(bo->map)) {
+ assert(ptr == MAP(bo->map));
+ return;
+ }
+
+ munmap(ptr, bytes(bo));
+}
+
uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo)
{
struct drm_gem_flink flink;
@@ -4961,6 +5011,19 @@ void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset)
}
}
+int kgem_bo_get_swizzling(struct kgem *kgem, struct kgem_bo *bo)
+{
+ struct drm_i915_gem_get_tiling tiling;
+
+ VG_CLEAR(tiling);
+ tiling.handle = bo->handle;
+ if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling))
+ return 0;
+
+ assert(bo->tiling == tiling.tiling_mode);
+ return tiling.swizzle_mode;
+}
+
struct kgem_bo *
kgem_replace_bo(struct kgem *kgem,
struct kgem_bo *src,