summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-07-20 09:51:46 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-07-20 09:51:46 +0100
commit8e6e8a2fa8adda9ae9be8a88fbb14851e9d2df2e (patch)
tree62b53baf90b1456cba65cfd9617609c6674f13c3
parent979035bb9ce04db5fe30efa4f6daab0a40f6af57 (diff)
sna: Allow the snoopable upload buffer to take pages from the CPU vma cache
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.c89
1 files changed, 39 insertions, 50 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index eeb67740..5361fa6d 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3972,26 +3972,54 @@ search_snoopable_buffer(struct kgem *kgem, unsigned alloc)
return NULL;
}
+static void
+init_buffer_from_bo(struct kgem_partial_bo *bo, struct kgem_bo *old)
+{
+ DBG(("%s: reusing handle=%d for buffer\n",
+ __FUNCTION__, old->handle));
+
+ memcpy(&bo->base, old, sizeof(*old));
+ if (old->rq)
+ list_replace(&old->request, &bo->base.request);
+ else
+ list_init(&bo->base.request);
+ list_replace(&old->vma, &bo->base.vma);
+ list_init(&bo->base.list);
+ free(old);
+ bo->base.refcnt = 1;
+
+ assert(bo->base.tiling == I915_TILING_NONE);
+}
+
static struct kgem_partial_bo *
create_snoopable_buffer(struct kgem *kgem, unsigned alloc)
{
struct kgem_partial_bo *bo;
if (kgem->has_cacheing) {
+ struct kgem_bo *old;
uint32_t handle;
- handle = gem_create(kgem->fd, alloc);
- if (handle == 0)
+ bo = malloc(sizeof(*bo));
+ if (bo == NULL)
return NULL;
- if (!gem_set_cacheing(kgem->fd, handle, SNOOPED)) {
- gem_close(kgem->fd, handle);
+ old = search_linear_cache(kgem, alloc,
+ CREATE_INACTIVE | CREATE_CPU_MAP | CREATE_EXACT);
+ if (old) {
+ init_buffer_from_bo(bo, old);
+ return bo;
+ }
+
+ handle = gem_create(kgem->fd, alloc);
+ if (handle == 0) {
+ free(bo);
return NULL;
}
- bo = malloc(sizeof(*bo));
- if (bo == NULL) {
+ if (!gem_set_cacheing(kgem->fd, handle, SNOOPED)) {
gem_close(kgem->fd, handle);
+ free(bo);
return NULL;
}
@@ -4155,18 +4183,7 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
if (old == NULL)
old = search_linear_cache(kgem, NUM_PAGES(size), CREATE_INACTIVE | CREATE_CPU_MAP);
if (old) {
- DBG(("%s: reusing handle=%d for buffer\n",
- __FUNCTION__, old->handle));
-
- memcpy(&bo->base, old, sizeof(*old));
- if (old->rq)
- list_replace(&old->request, &bo->base.request);
- else
- list_init(&bo->base.request);
- list_replace(&old->vma, &bo->base.vma);
- list_init(&bo->base.list);
- free(old);
- bo->base.refcnt = 1;
+ init_buffer_from_bo(bo, old);
} else {
uint32_t handle = gem_create(kgem->fd, alloc);
if (handle == 0 ||
@@ -4251,16 +4268,7 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
if (bo == NULL)
return NULL;
- memcpy(&bo->base, old, sizeof(*old));
- if (old->rq)
- list_replace(&old->request, &bo->base.request);
- else
- list_init(&bo->base.request);
- list_replace(&old->vma, &bo->base.vma);
- list_init(&bo->base.list);
- free(old);
-
- assert(bo->base.tiling == I915_TILING_NONE);
+ init_buffer_from_bo(bo, old);
assert(num_pages(&bo->base) >= NUM_PAGES(size));
bo->mem = kgem_bo_map(kgem, &bo->base);
@@ -4268,11 +4276,11 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
bo->need_io = false;
bo->base.io = true;
bo->mmapped = true;
- bo->base.refcnt = 1;
alloc = num_pages(&bo->base);
goto init;
} else {
+ bo->base.refcnt = 0;
kgem_bo_free(kgem, &bo->base);
bo = NULL;
}
@@ -4315,17 +4323,7 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
if (bo == NULL)
return NULL;
- memcpy(&bo->base, old, sizeof(*old));
- if (old->rq)
- list_replace(&old->request,
- &bo->base.request);
- else
- list_init(&bo->base.request);
- list_replace(&old->vma, &bo->base.vma);
- list_init(&bo->base.list);
- free(old);
- bo->base.refcnt = 1;
-
+ init_buffer_from_bo(bo, old);
bo->need_io = flags & KGEM_BUFFER_WRITE;
bo->base.io = true;
} else {
@@ -4345,16 +4343,7 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
DBG(("%s: reusing cpu map handle=%d for buffer\n",
__FUNCTION__, old->handle));
alloc = num_pages(old);
-
- memcpy(&bo->base, old, sizeof(*old));
- if (old->rq)
- list_replace(&old->request, &bo->base.request);
- else
- list_init(&bo->base.request);
- list_replace(&old->vma, &bo->base.vma);
- list_init(&bo->base.list);
- free(old);
- bo->base.refcnt = 1;
+ init_buffer_from_bo(bo, old);
} else {
uint32_t handle = gem_create(kgem->fd, alloc);
if (handle == 0 ||