summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sna/kgem.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index c957bbf2..20ca9b91 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -443,6 +443,19 @@ static void kgem_sna_flush(struct kgem *kgem)
sna_render_flush_solid(sna);
}
+static bool kgem_bo_rmfb(struct kgem *kgem, struct kgem_bo *bo)
+{
+ if (bo->scanout && bo->delta) {
+ DBG(("%s: releasing fb=%d for handle=%d\n",
+ __FUNCTION__, bo->delta, bo->handle));
+ /* XXX will leak if we are not DRM_MASTER. *shrug* */
+ do_ioctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &bo->delta);
+ bo->delta = 0;
+ return true;
+ } else
+ return false;
+}
+
static bool kgem_set_tiling(struct kgem *kgem, struct kgem_bo *bo,
int tiling, int stride)
{
@@ -487,6 +500,9 @@ restart:
goto restart;
}
+ if (err == EBUSY && kgem_bo_rmfb(kgem, bo))
+ goto restart;
+
ERR(("%s: failed to set-tiling(tiling=%d, pitch=%d) for handle=%d: %d\n",
__FUNCTION__, tiling, stride, bo->handle, err));
return false;
@@ -2517,17 +2533,6 @@ static void kgem_bo_binding_free(struct kgem *kgem, struct kgem_bo *bo)
}
}
-static void kgem_bo_rmfb(struct kgem *kgem, struct kgem_bo *bo)
-{
- if (bo->scanout && bo->delta) {
- DBG(("%s: releasing fb=%d for handle=%d\n",
- __FUNCTION__, bo->delta, bo->handle));
- /* XXX will leak if we are not DRM_MASTER. *shrug* */
- do_ioctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &bo->delta);
- bo->delta = 0;
- }
-}
-
static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo)
{
DBG(("%s: handle=%d, size=%d\n", __FUNCTION__, bo->handle, bytes(bo)));