summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drm_bo.c48
-rw-r--r--linux-core/drm_fence.c4
-rw-r--r--shared-core/drm.h6
3 files changed, 47 insertions, 11 deletions
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c
index 7f50bacf..1f0bbba5 100644
--- a/linux-core/drm_bo.c
+++ b/linux-core/drm_bo.c
@@ -299,7 +299,8 @@ int drm_fence_buffer_objects(drm_file_t * priv,
* Wait until the buffer is idle.
*/
-static int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int no_wait)
+static int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals,
+ int no_wait)
{
drm_fence_object_t *fence = bo->fence;
@@ -317,7 +318,7 @@ static int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int no_wait)
return -EBUSY;
ret =
- drm_fence_object_wait(dev, fence, lazy, !lazy,
+ drm_fence_object_wait(dev, fence, lazy, ignore_signals,
bo->fence_flags);
if (ret)
return ret;
@@ -351,7 +352,7 @@ static int drm_bo_evict(drm_buffer_object_t * bo, int tt, int no_wait)
if (!tt && !bo->vram)
goto out;
- ret = drm_bo_wait(bo, 0, no_wait);
+ ret = drm_bo_wait(bo, 0, 0, no_wait);
if (ret)
goto out;
@@ -805,7 +806,7 @@ static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle,
while (1) {
if (atomic_inc_and_test(&bo->mapped)) {
- ret = drm_bo_wait(bo, 0, no_wait);
+ ret = drm_bo_wait(bo, 0, 0, no_wait);
if (ret) {
atomic_dec(&bo->mapped);
goto out;
@@ -926,7 +927,7 @@ static int drm_bo_move_buffer(drm_buffer_object_t * bo, uint32_t new_flags,
* Wait for outstanding fences.
*/
- ret = drm_bo_wait(bo, 0, no_wait);
+ ret = drm_bo_wait(bo, 0, 0, no_wait);
if (ret == -EINTR)
return -EAGAIN;
@@ -1073,6 +1074,34 @@ static int drm_bo_handle_info(drm_file_t * priv, uint32_t handle,
(void)drm_bo_busy(bo);
drm_bo_fill_rep_arg(bo, rep);
mutex_unlock(&bo->mutex);
+ drm_bo_usage_deref_unlocked(bo->dev, bo);
+ return 0;
+}
+
+static int drm_bo_handle_wait(drm_file_t * priv, uint32_t handle,
+ uint32_t hint, drm_bo_arg_reply_t * rep)
+{
+ drm_buffer_object_t *bo;
+ int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
+ int ret;
+
+ bo = drm_lookup_buffer_object(priv, handle, 1);
+ if (!bo) {
+ return -EINVAL;
+ }
+ mutex_lock(&bo->mutex);
+ ret = drm_bo_wait_unfenced(bo, no_wait, 0);
+ if (ret)
+ goto out;
+ ret = drm_bo_wait(bo, hint & DRM_BO_HINT_WAIT_LAZY,
+ 0, no_wait);
+ if (ret)
+ goto out;
+
+ drm_bo_fill_rep_arg(bo, rep);
+out:
+ mutex_unlock(&bo->mutex);
+ drm_bo_usage_deref_unlocked(bo->dev, bo);
return 0;
}
@@ -1348,6 +1377,13 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
case drm_bo_info:
rep.ret = drm_bo_handle_info(priv, req->handle, &rep);
break;
+ case drm_bo_wait_idle:
+ rep.ret = drm_bo_handle_wait(priv, req->handle,
+ req->hint, &rep);
+ break;
+ case drm_bo_ref_fence:
+ rep.ret = -EINVAL;
+ DRM_ERROR("Function is not implemented yet.\n");
default:
rep.ret = -EINVAL;
}
@@ -1386,7 +1422,7 @@ static void drm_bo_force_clean(drm_device_t * dev)
if (nice_mode) {
unsigned long _end = jiffies + 3 * DRM_HZ;
do {
- ret = drm_bo_wait(entry, 0, 0);
+ ret = drm_bo_wait(entry, 0, 1, 0);
} while ((ret == -EINTR) &&
!time_after_eq(jiffies, _end));
} else {
diff --git a/linux-core/drm_fence.c b/linux-core/drm_fence.c
index 622cad10..1deeaaa5 100644
--- a/linux-core/drm_fence.c
+++ b/linux-core/drm_fence.c
@@ -567,9 +567,7 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS)
ret =
drm_fence_object_wait(dev, fence,
arg.flags & DRM_FENCE_FLAG_WAIT_LAZY,
- arg.
- flags &
- DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS,
+ 0,
arg.type);
break;
case drm_fence_emit:
diff --git a/shared-core/drm.h b/shared-core/drm.h
index a7d778ce..1a43e0af 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -726,7 +726,7 @@ typedef struct drm_ttm_arg {
#define DRM_BO_HINT_DONT_BLOCK 0x00000002
/* Don't place this buffer on the unfenced list.*/
#define DRM_BO_HINT_DONT_FENCE 0x00000004
-
+#define DRM_BO_HINT_WAIT_LAZY 0x00000008
@@ -759,7 +759,9 @@ typedef struct drm_bo_arg_request {
drm_bo_destroy,
drm_bo_reference,
drm_bo_unreference,
- drm_bo_info
+ drm_bo_info,
+ drm_bo_wait_idle,
+ drm_bo_ref_fence
} op;
} drm_bo_arg_request_t;