Export buffer info on map and validate ioctls.
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Fri, 1 Sep 2006 14:38:06 +0000 (16:38 +0200)
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Fri, 1 Sep 2006 14:38:06 +0000 (16:38 +0200)
Add an info ioctl operation.

libdrm/xf86drm.c
libdrm/xf86mm.h
linux-core/drm_bo.c
shared-core/drm.h

index 41ad89c..aa1a599 100644 (file)
@@ -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;
index aaee3c0..a8458b1 100644 (file)
@@ -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;
index 1c71f34..317b5f7 100644 (file)
@@ -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);
index f76fd86..f781abc 100644 (file)
@@ -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;