aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-09-01 16:38:06 +0200
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-09-01 16:38:06 +0200
commitef8e618cf30ab7dcbe8c7211e0c2508c5520a669 (patch)
treea2e176f15e84526ea09e28f12508468125c91d8d
parent11f51a9a877d1231551e8c6482a6f70daf380cdd (diff)
Export buffer info on map and validate ioctls.
Add an info ioctl operation.
-rw-r--r--libdrm/xf86drm.c84
-rw-r--r--libdrm/xf86mm.h2
-rw-r--r--linux-core/drm_bo.c115
-rw-r--r--shared-core/drm.h12
4 files changed, 164 insertions, 49 deletions
diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c
index 41ad89cb..aa1a5998 100644
--- a/libdrm/xf86drm.c
+++ b/libdrm/xf86drm.c
@@ -2567,6 +2567,22 @@ int drmCreateBufList(int numTarget, drmBOList *list)
return drmAdjustListNodes(list);
}
+static void drmBOCopyReply(const drm_bo_arg_reply_t *rep,
+ drmBO *buf)
+{
+ buf->handle = rep->handle;
+ buf->flags = rep->flags;
+ buf->size = rep->size;
+ buf->offset = rep->offset;
+ buf->mapHandle = rep->arg_handle;
+ buf->mask = rep->mask;
+ buf->start = rep->buffer_start;
+ buf->fenceFlags = rep->fence_flags;
+ buf->replyFlags = rep->rep_flags;
+}
+
+
+
int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
void *user_buffer, drm_bo_type_t type, unsigned mask,
unsigned hint, drmBO *buf)
@@ -2612,16 +2628,10 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
return rep->ret;
}
- buf->handle = rep->handle;
- buf->flags = rep->flags;
- buf->size = rep->size;
- buf->offset = rep->offset;
- buf->mapHandle = rep->arg_handle;
+ drmBOCopyReply(rep, buf);
buf->mapVirtual = NULL;
buf->mapCount = 0;
buf->virtual = NULL;
- buf->mask = rep->mask;
- buf->start = rep->buffer_start;
return 0;
}
@@ -2671,17 +2681,12 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf)
return rep->ret;
}
- buf->handle = rep->handle;
+ drmBOCopyReply(rep, buf);
buf->type = drm_bo_type_dc;
- buf->flags = rep->flags;
- buf->size = rep->size;
- buf->offset = rep->offset;
- buf->mapHandle = rep->arg_handle;
buf->mapVirtual = NULL;
buf->mapCount = 0;
buf->virtual = NULL;
- buf->mask = rep->mask;
- buf->start = rep->buffer_start;
+
return 0;
}
@@ -2777,6 +2782,7 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
buf->mapFlags = mapFlags;
fprintf(stderr, "Address is 0x%08x\n", address);
*address = buf->virtual;
+ drmBOCopyReply(rep, buf);
return 0;
}
@@ -2838,9 +2844,7 @@ int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask,
if (rep->ret)
return rep->ret;
- buf->offset = rep->offset;
- buf->flags = rep->flags;
- buf->mask = rep->mask;
+ drmBOCopyReply(rep, buf);
return 0;
}
@@ -2869,8 +2873,46 @@ int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle)
return rep->ret;
return 0;
}
-
+int drmBOInfo(int fd, drmBO *buf)
+{
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.req;
+ drm_bo_arg_reply_t *rep = &arg.rep;
+ int ret = 0;
+
+ arg.handled = 0;
+ req->handle = buf->handle;
+ req->op = drm_bo_info;
+ req->next = 0;
+
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+
+ if (ret)
+ return ret;
+ if (!arg.handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
+ drmBOCopyReply(rep, buf);
+ return 0;
+}
+
+int drmBufBusy(int fd, drmBO *buf, int *busy)
+{
+ if (!(buf->flags & DRM_BO_FLAG_SHAREABLE) &&
+ !(buf->replyFlags & DRM_BO_REP_BUSY)) {
+ *busy = 0;
+ return 0;
+ } else {
+ int ret = drmBOInfo(fd, buf);
+ if (ret)
+ return ret;
+ *busy = (buf->replyFlags & DRM_BO_REP_BUSY);
+ return 0;
+ }
+}
+
int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags,
unsigned mask,
@@ -2978,9 +3020,7 @@ int drmBOValidateList(int fd, drmBOList *list)
return rep->ret;
buf = node->buf;
- buf->offset = rep->offset;
- buf->flags = rep->flags;
- buf->mask = rep->mask;
+ drmBOCopyReply(rep, buf);
}
return 0;
@@ -2997,6 +3037,7 @@ int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle)
drm_bo_arg_reply_t *rep;
drm_u64_t *prevNext = NULL;
drmBO *buf;
+ unsigned fence_flags;
int ret;
first = NULL;
@@ -3040,6 +3081,7 @@ int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle)
return -EFAULT;
if (rep->ret)
return rep->ret;
+ drmBOCopyReply(rep, buf);
}
return 0;
diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h
index aaee3c0b..a8458b15 100644
--- a/libdrm/xf86mm.h
+++ b/libdrm/xf86mm.h
@@ -92,6 +92,8 @@ typedef struct _drmBO{
unsigned long size;
unsigned long offset;
unsigned long start;
+ unsigned replyFlags;
+ unsigned fenceFlags;
void *virtual;
void *mapVirtual;
int mapCount;
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c
index 1c71f345..317b5f7a 100644
--- a/linux-core/drm_bo.c
+++ b/linux-core/drm_bo.c
@@ -601,6 +601,32 @@ drm_buffer_object_t *drm_lookup_buffer_object(drm_file_t * priv,
/*
* Call bo->mutex locked.
* Returns 1 if the buffer is currently rendered to or from. 0 otherwise.
+ * Doesn't do any fence flushing as opposed to the drm_bo_busy function.
+ */
+
+
+static int drm_bo_quick_busy(drm_buffer_object_t *bo)
+{
+ drm_fence_object_t *fence = bo->fence;
+
+
+ BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
+ if (fence) {
+ drm_device_t *dev = bo->dev;
+ if (drm_fence_object_signaled(fence, bo->fence_flags)) {
+ drm_fence_usage_deref_unlocked(dev, fence);
+ bo->fence = NULL;
+ return 0;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+
+/*
+ * Call bo->mutex locked.
+ * Returns 1 if the buffer is currently rendered to or from. 0 otherwise.
*/
static int drm_bo_busy(drm_buffer_object_t * bo)
@@ -719,8 +745,36 @@ static int drm_bo_wait_unfenced(drm_buffer_object_t *bo, int no_wait,
return 0;
}
+/*
+ * Fill in the ioctl reply argument with buffer info.
+ * Bo locked.
+ */
+static void drm_bo_fill_rep_arg(drm_buffer_object_t * bo,
+ drm_bo_arg_reply_t * rep)
+{
+ rep->handle = bo->base.hash.key;
+ rep->flags = bo->flags;
+ rep->size = bo->num_pages * PAGE_SIZE;
+ rep->offset = bo->offset;
+
+ if (bo->ttm_object) {
+ rep->arg_handle = bo->ttm_object->map_list.user_token;
+ } else {
+ rep->arg_handle = 0;
+ }
+
+ rep->mask = bo->mask;
+ rep->buffer_start = bo->buffer_start;
+ rep->fence_flags = bo->fence_flags;
+ rep->rep_flags = 0;
+
+ if ((bo->priv_flags & _DRM_BO_FLAG_UNFENCED) ||
+ drm_bo_quick_busy(bo)) {
+ DRM_FLAG_MASKED(rep->rep_flags, DRM_BO_REP_BUSY, DRM_BO_REP_BUSY);
+ }
+}
/*
@@ -731,7 +785,8 @@ static int drm_bo_wait_unfenced(drm_buffer_object_t *bo, int no_wait,
*/
static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle,
- uint32_t map_flags, int no_wait)
+ uint32_t map_flags, int no_wait,
+ drm_bo_arg_reply_t *rep)
{
drm_buffer_object_t *bo;
drm_device_t *dev = priv->head->dev;
@@ -794,7 +849,8 @@ static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle,
if (atomic_add_negative(-1, &bo->mapped))
DRM_WAKEUP(&bo->event_queue);
- }
+ } else
+ drm_bo_fill_rep_arg(bo, rep);
out:
mutex_unlock(&bo->mutex);
drm_bo_usage_deref_unlocked(dev, bo);
@@ -973,7 +1029,8 @@ static int drm_buffer_object_validate(drm_buffer_object_t * bo,
}
static int drm_bo_handle_validate(drm_file_t * priv, uint32_t handle,
- uint32_t flags, uint32_t mask, uint32_t hint)
+ uint32_t flags, uint32_t mask, uint32_t hint,
+ drm_bo_arg_reply_t *rep)
{
drm_buffer_object_t *bo;
drm_device_t *dev = priv->head->dev;
@@ -1001,13 +1058,33 @@ static int drm_bo_handle_validate(drm_file_t * priv, uint32_t handle,
ret = drm_buffer_object_validate(bo, new_flags, !(hint & DRM_BO_HINT_DONT_FENCE),
no_wait);
+ drm_bo_fill_rep_arg(bo, rep);
-out:
+out:
+
mutex_unlock(&bo->mutex);
drm_bo_usage_deref_unlocked(dev, bo);
return ret;
}
+static int drm_bo_handle_info(drm_file_t * priv, uint32_t handle,
+ drm_bo_arg_reply_t *rep)
+{
+ drm_buffer_object_t *bo;
+
+ bo = drm_lookup_buffer_object(priv, handle, 1);
+ if (!bo) {
+ return -EINVAL;
+ }
+ mutex_lock(&bo->mutex);
+ if (!(bo->priv_flags & _DRM_BO_FLAG_UNFENCED))
+ (void) drm_bo_busy(bo);
+ drm_bo_fill_rep_arg(bo, rep);
+ mutex_unlock(&bo->mutex);
+ return 0;
+}
+
+
/*
* Call bo->mutex locked.
*/
@@ -1167,24 +1244,6 @@ static int drm_bo_add_user_object(drm_file_t * priv, drm_buffer_object_t * bo,
return ret;
}
-static void drm_bo_fill_rep_arg(const drm_buffer_object_t * bo,
- drm_bo_arg_reply_t * rep)
-{
- rep->handle = bo->base.hash.key;
- rep->flags = bo->flags;
- rep->size = bo->num_pages * PAGE_SIZE;
- rep->offset = bo->offset;
-
- if (bo->ttm_object) {
- rep->arg_handle = bo->ttm_object->map_list.user_token;
- } else {
- rep->arg_handle = 0;
- }
-
- rep->mask = bo->mask;
- rep->buffer_start = bo->buffer_start;
-}
-
static int drm_bo_lock_test(drm_device_t * dev, struct file *filp)
{
LOCK_TEST_WITH_RETURN(dev, filp);
@@ -1249,7 +1308,8 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
rep.ret = drm_buffer_object_map(priv, req->handle,
req->mask,
req->hint &
- DRM_BO_HINT_DONT_BLOCK);
+ DRM_BO_HINT_DONT_BLOCK,
+ &rep);
break;
case drm_bo_destroy:
mutex_lock(&dev->struct_mutex);
@@ -1289,7 +1349,8 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
break;
rep.ret =
drm_bo_handle_validate(priv, req->handle, req->mask,
- req->arg_handle, req->hint);
+ req->arg_handle, req->hint,
+ &rep);
break;
case drm_bo_fence:
rep.ret = drm_bo_lock_test(dev, filp);
@@ -1297,6 +1358,9 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
break;
/**/
break;
+ case drm_bo_info:
+ rep.ret = drm_bo_handle_info(priv, req->handle, &rep);
+ break;
default:
rep.ret = -EINVAL;
}
@@ -1443,9 +1507,6 @@ int drm_mm_init_ioctl(DRM_IOCTL_ARGS)
}
if (arg.req.tt_p_size) {
- DRM_ERROR("Initializing TT 0x%08x 0x%08x\n",
- arg.req.tt_p_offset,
- arg.req.tt_p_size);
ret = drm_mm_init(&bm->tt_manager,
arg.req.tt_p_offset,
arg.req.tt_p_size);
diff --git a/shared-core/drm.h b/shared-core/drm.h
index f76fd86f..f781abc6 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -758,10 +758,18 @@ typedef struct drm_bo_arg_request {
drm_bo_fence,
drm_bo_destroy,
drm_bo_reference,
- drm_bo_unreference
+ drm_bo_unreference,
+ drm_bo_info
} op;
} drm_bo_arg_request_t;
+
+/*
+ * Reply flags
+ */
+
+#define DRM_BO_REP_BUSY 0x00000001
+
typedef struct drm_bo_arg_reply {
int ret;
unsigned handle;
@@ -771,6 +779,8 @@ typedef struct drm_bo_arg_reply {
unsigned arg_handle;
unsigned mask;
drm_u64_t buffer_start;
+ unsigned fence_flags;
+ unsigned rep_flags;
}drm_bo_arg_reply_t;