summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-11-08 23:42:10 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-12-07 11:39:14 +0000
commit4bfc5e90f54be1b0997dec9e81796d67b376a01f (patch)
treea75427acfd24976887e3d2d5cbc6cd6b30fa773e
parent1d2fa5731b7ecfe34a8af809e45bcd3b0b70c890 (diff)
sna: Mark proxies as dirty on first relocation
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.c9
-rw-r--r--src/sna/kgem.h21
2 files changed, 20 insertions, 10 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index cc86d22c..bf457ce9 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -111,7 +111,6 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
#define LOCAL_I915_PARAM_HAS_NO_RELOC 24
#define LOCAL_I915_PARAM_HAS_HANDLE_LUT 25
-#define LOCAL_EXEC_OBJECT_WRITE (1<<2)
#define LOCAL_I915_EXEC_NO_RELOC (1<<10)
#define LOCAL_I915_EXEC_HANDLE_LUT (1<<11)
@@ -3907,6 +3906,9 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
bo->exec = &_kgem_dummy_exec;
}
+ if (read_write_domain & 0x7fff && !bo->dirty)
+ __kgem_bo_mark_dirty(bo);
+
bo = bo->proxy;
assert(bo->refcnt);
assert(!bo->purged);
@@ -3931,10 +3933,9 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
kgem->reloc[index].target_handle = bo->target_handle;
kgem->reloc[index].presumed_offset = bo->presumed_offset;
- if (read_write_domain & 0x7fff) {
+ if (read_write_domain & 0x7fff && !bo->dirty) {
assert(!bo->snoop || kgem->can_blt_cpu);
- bo->exec->flags |= LOCAL_EXEC_OBJECT_WRITE;
- kgem_bo_mark_dirty(bo);
+ __kgem_bo_mark_dirty(bo);
}
delta += bo->presumed_offset;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 6a3149af..2d04b53c 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -141,6 +141,7 @@ struct kgem {
uint32_t batch_flags;
#define I915_EXEC_SECURE (1<<9)
+#define LOCAL_EXEC_OBJECT_WRITE (1<<2)
uint16_t nbatch;
uint16_t surface;
@@ -571,19 +572,27 @@ static inline bool kgem_bo_is_dirty(struct kgem_bo *bo)
return bo->dirty;
}
+static inline void __kgem_bo_mark_dirty(struct kgem_bo *bo)
+{
+ DBG(("%s: handle=%d (proxy? %d)\n", __FUNCTION__,
+ bo->handle, bo->proxy != NULL));
+
+ bo->exec->flags |= LOCAL_EXEC_OBJECT_WRITE;
+ bo->needs_flush = bo->dirty = true;
+ list_move(&bo->request, &bo->rq->buffers);
+}
+
static inline void kgem_bo_mark_dirty(struct kgem_bo *bo)
{
assert(bo->refcnt);
do {
- if (bo->dirty)
- return;
-
- DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
assert(bo->exec);
assert(bo->rq);
- bo->needs_flush = bo->dirty = true;
- list_move(&bo->request, &bo->rq->buffers);
+ if (bo->dirty)
+ return;
+
+ __kgem_bo_mark_dirty(bo);
} while ((bo = bo->proxy));
}