summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-06-13 15:06:13 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-06-13 15:06:13 +0100
commitdd87aa8f85c4bafa105fd881a0cce45bda6143df (patch)
tree69b80fcb8b2b341b365795bef143f4fba355a094
parent8322e3e5c6ed19e029f365d869c80388863c424d (diff)
sna: Track the pageflip bo's busyness
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.c2
-rw-r--r--src/sna/kgem.h13
-rw-r--r--src/sna/sna_display.c13
-rw-r--r--src/sna/sna_dri2.c2
4 files changed, 25 insertions, 5 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 7582e075..88f1b911 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -118,8 +118,6 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
#define MAKE_USER_MAP(ptr) ((void*)((uintptr_t)(ptr) | 1))
#define IS_USER_MAP(ptr) ((uintptr_t)(ptr) & 1)
-#define MAKE_REQUEST(rq, ring) ((struct kgem_request *)((uintptr_t)(rq) | (ring)))
-
#define LOCAL_I915_PARAM_HAS_BLT 11
#define LOCAL_I915_PARAM_HAS_RELAXED_FENCING 12
#define LOCAL_I915_PARAM_HAS_RELAXED_DELTA 15
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index a52287d1..8ba7a9ef 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -50,6 +50,8 @@ struct kgem_bo {
#define RQ(rq) ((struct kgem_request *)((uintptr_t)(rq) & ~3))
#define RQ_RING(rq) ((uintptr_t)(rq) & 3)
#define RQ_IS_BLT(rq) (RQ_RING(rq) == KGEM_BLT)
+#define MAKE_REQUEST(rq, ring) ((struct kgem_request *)((uintptr_t)(rq) | (ring)))
+
struct drm_i915_gem_exec_object2 *exec;
struct kgem_bo *proxy;
@@ -569,10 +571,17 @@ void kgem_bo_pair_undo(struct kgem *kgem, struct kgem_bo *a, struct kgem_bo *b);
bool __kgem_busy(struct kgem *kgem, int handle);
-static inline void kgem_bo_mark_busy(struct kgem_bo *bo, int ring)
+static inline void kgem_bo_mark_busy(struct kgem *kgem, struct kgem_bo *bo, int ring)
{
assert(bo->refcnt);
- bo->rq = (struct kgem_request *)((uintptr_t)bo->rq | ring);
+ bo->needs_flush = true;
+ if (bo->rq) {
+ bo->rq = MAKE_REQUEST(RQ(bo->rq), ring);
+ } else {
+ bo->rq = MAKE_REQUEST(kgem, ring);
+ list_add(&bo->request, &kgem->flushing);
+ kgem->need_retire = true;
+ }
}
inline static void __kgem_bo_clear_busy(struct kgem_bo *bo)
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 5e6de551..eeab3498 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -6350,6 +6350,19 @@ fixup_flip:
crtc->flip_handler = shadow_flip_handler;
crtc->flip_bo = kgem_bo_reference(flip_bo);
crtc->flip_bo->active_scanout++;
+
+ {
+ struct drm_i915_gem_busy busy = { flip_bo->handle };
+ if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_BUSY, &busy) == 0) {
+ if (busy.busy) {
+ int mode = KGEM_RENDER;
+ if (busy.busy & (1 << 17))
+ mode = KGEM_BLT;
+ kgem_bo_mark_busy(&sna->kgem, flip_bo, mode);
+ } else
+ __kgem_bo_clear_busy(flip_bo);
+ }
+ }
}
DBG(("%s: flipped %d outputs, shadow active? %d\n",
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 21feed58..efc790fa 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -790,7 +790,7 @@ static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kg
mode = KGEM_RENDER;
if (busy.busy & (1 << 17))
mode = KGEM_BLT;
- kgem_bo_mark_busy(busy.handle == src->handle ? src : dst, mode);
+ kgem_bo_mark_busy(&sna->kgem, busy.handle == src->handle ? src : dst, mode);
_kgem_set_mode(&sna->kgem, mode);
}