xf86-video-intel: 2 commits - src/sna/kgem.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Dec 23 03:19:20 PST 2011


 src/sna/kgem.c |   57 ++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 13 deletions(-)

New commits:
commit d9ca113a83177562cde3537bf955164c6950cbd0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 23 10:06:58 2011 +0000

    sna: Trim the unused pages from the batch between the last command and surface
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index b74777c..0ea9d39 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1059,7 +1059,7 @@ static void kgem_cleanup(struct kgem *kgem)
 	kgem_close_inactive(kgem);
 }
 
-static int kgem_batch_write(struct kgem *kgem, uint32_t handle)
+static int kgem_batch_write(struct kgem *kgem, uint32_t handle, uint32_t size)
 {
 	int ret;
 
@@ -1072,10 +1072,12 @@ static int kgem_batch_write(struct kgem *kgem, uint32_t handle)
 				 kgem->batch);
 
 	/* Are the batch pages conjoint with the surface pages? */
-	if (kgem->surface < kgem->nbatch + PAGE_SIZE/4)
+	if (kgem->surface < kgem->nbatch + PAGE_SIZE/4) {
+		assert(size == sizeof(kgem->batch));
 		return gem_write(kgem->fd, handle,
 				 0, sizeof(kgem->batch),
 				 kgem->batch);
+	}
 
 	/* Disjoint surface/batch, upload separately */
 	ret = gem_write(kgem->fd, handle,
@@ -1085,7 +1087,7 @@ static int kgem_batch_write(struct kgem *kgem, uint32_t handle)
 		return ret;
 
 	return gem_write(kgem->fd, handle,
-			sizeof(uint32_t)*kgem->surface,
+			sizeof(uint32_t)*kgem->surface - (sizeof(kgem->batch)-size),
 			sizeof(kgem->batch) - sizeof(uint32_t)*kgem->surface,
 			kgem->batch + kgem->surface);
 }
@@ -1134,6 +1136,31 @@ void kgem_reset(struct kgem *kgem)
 	kgem_sna_reset(kgem);
 }
 
+static int compact_batch_surface(struct kgem *kgem)
+{
+	int size, shrink, n;
+
+	/* See if we can pack the contents into one or two pages */
+	size = ARRAY_SIZE(kgem->batch) - kgem->surface + kgem->nbatch;
+	if (size > 2048)
+		return sizeof(kgem->batch);
+	else if (size > 1024)
+		size = 8192, shrink = 2*4096;
+	else
+		size = 4096, shrink = 3*4096;
+
+	for (n = 0; n < kgem->nreloc; n++) {
+		if (kgem->reloc[n].read_domains == I915_GEM_DOMAIN_INSTRUCTION &&
+		    kgem->reloc[n].target_handle == 0)
+			kgem->reloc[n].delta -= shrink;
+
+		if (kgem->reloc[n].offset >= size)
+			kgem->reloc[n].offset -= shrink;
+	}
+
+	return size;
+}
+
 void _kgem_submit(struct kgem *kgem)
 {
 	struct kgem_request *rq;
@@ -1164,7 +1191,7 @@ void _kgem_submit(struct kgem *kgem)
 
 	rq = kgem->next_request;
 	if (kgem->surface != ARRAY_SIZE(kgem->batch))
-		size = sizeof(kgem->batch);
+		size = compact_batch_surface(kgem);
 	else
 		size = kgem->nbatch * sizeof(kgem->batch[0]);
 	rq->bo = kgem_create_linear(kgem, size);
@@ -1189,7 +1216,7 @@ void _kgem_submit(struct kgem *kgem)
 		kgem_finish_partials(kgem);
 
 		assert(!rq->bo->needs_flush);
-		if (kgem_batch_write(kgem, handle) == 0) {
+		if (kgem_batch_write(kgem, handle, size) == 0) {
 			struct drm_i915_gem_execbuffer2 execbuf;
 			int ret, retry = 3;
 
commit 013eda17e91ff421cd1ef70470e3575f1183fcbd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 23 10:40:58 2011 +0000

    sna: Free the additional bindings on proxies

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 53f100c..b74777c 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -697,20 +697,25 @@ static void kgem_fixup_self_relocs(struct kgem *kgem, struct kgem_bo *bo)
 	}
 }
 
-static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo)
+static void kgem_bo_binding_free(struct kgem *kgem, struct kgem_bo *bo)
 {
 	struct kgem_bo_binding *b;
 
-	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
-	assert(bo->refcnt == 0);
-	assert(bo->exec == NULL);
-
 	b = bo->binding.next;
 	while (b) {
 		struct kgem_bo_binding *next = b->next;
 		free (b);
 		b = next;
 	}
+}
+
+static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo)
+{
+	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
+	assert(bo->refcnt == 0);
+	assert(bo->exec == NULL);
+
+	kgem_bo_binding_free(kgem, bo);
 
 	if (bo->map) {
 		DBG(("%s: releasing %s vma for handle=%d, count=%d\n",
@@ -1991,10 +1996,9 @@ skip_active_search:
 void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 {
 	if (bo->proxy) {
-		kgem_bo_unref(kgem, bo->proxy);
-
-		assert(bo->binding.next == NULL);
 		assert(bo->map == NULL);
+		kgem_bo_unref(kgem, bo->proxy);
+		kgem_bo_binding_free(kgem, bo);
 		_list_del(&bo->request);
 		free(bo);
 		return;


More information about the xorg-commit mailing list