OSDN Git Service

Fence all unfenced buffers function.
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Tue, 5 Sep 2006 16:00:25 +0000 (18:00 +0200)
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Tue, 5 Sep 2006 16:00:25 +0000 (18:00 +0200)
libdrm/xf86drm.c
libdrm/xf86drm.h
linux-core/drmP.h
linux-core/drm_bo.c
linux-core/drm_fence.c
shared-core/drm.h

index 068d0fb..6d08742 100644 (file)
@@ -2259,6 +2259,21 @@ int drmFenceCreate(int fd, int shareable, int class,unsigned type,
     fence->signaled = 0;
     return 0;
 }
     fence->signaled = 0;
     return 0;
 }
+
+int drmFenceBuffers(int fd, int shareable, drmFence *fence)
+{
+    drm_fence_arg_t arg;
+    
+    arg.flags = (shareable) ? DRM_FENCE_FLAG_SHAREABLE : 0;
+    arg.op = drm_fence_buffers;
+    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+       return -errno;
+    fence->handle = arg.handle;
+    fence->class = arg.class;
+    fence->type = arg.type;
+    fence->signaled = 0;
+    return 0;
+}
     
 int drmFenceDestroy(int fd, const drmFence *fence)
 {
     
 int drmFenceDestroy(int fd, const drmFence *fence)
 {
index f257ded..be1eeef 100644 (file)
@@ -626,6 +626,7 @@ extern int           drmFenceSignaled(int fd, drmFence *fence);
 extern int           drmFenceWait(int fd, drmFence *fence, unsigned flush_type, 
                                  int lazy, int ignore_signals);
 extern int           drmFenceEmit(int fd, drmFence *fence, unsigned emit_type);
 extern int           drmFenceWait(int fd, drmFence *fence, unsigned flush_type, 
                                  int lazy, int ignore_signals);
 extern int           drmFenceEmit(int fd, drmFence *fence, unsigned emit_type);
+extern int           drmFenceBuffers(int fd, int shareable, drmFence *fence);
 
 /* TTMS */
 extern int           drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, 
 
 /* TTMS */
 extern int           drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, 
index 2376637..7de7422 100644 (file)
@@ -1379,10 +1379,16 @@ extern void drm_fence_usage_deref_locked(drm_device_t * dev,
                                         drm_fence_object_t * fence);
 extern void drm_fence_usage_deref_unlocked(drm_device_t * dev,
                                         drm_fence_object_t * fence);
                                         drm_fence_object_t * fence);
 extern void drm_fence_usage_deref_unlocked(drm_device_t * dev,
                                         drm_fence_object_t * fence);
-extern int drm_fence_object_init(drm_device_t * dev, uint32_t type, int emit,
-                                drm_fence_object_t * fence);
 extern int drm_fence_object_wait(drm_device_t * dev, drm_fence_object_t * fence,
                                 int lazy, int ignore_signals, uint32_t mask);
 extern int drm_fence_object_wait(drm_device_t * dev, drm_fence_object_t * fence,
                                 int lazy, int ignore_signals, uint32_t mask);
+extern int drm_fence_object_create(drm_device_t *dev, uint32_t type,
+                                  int emit, drm_fence_object_t **c_fence);
+extern int drm_fence_add_user_object(drm_file_t *priv, 
+                                    drm_fence_object_t *fence,
+                                    int shareable);
+
+
+
 
 
 extern int drm_fence_ioctl(DRM_IOCTL_ARGS);
 
 
 extern int drm_fence_ioctl(DRM_IOCTL_ARGS);
@@ -1394,6 +1400,10 @@ extern int drm_fence_ioctl(DRM_IOCTL_ARGS);
 extern int drm_bo_ioctl(DRM_IOCTL_ARGS);
 extern int drm_mm_init_ioctl(DRM_IOCTL_ARGS);
 extern int drm_bo_clean_mm(drm_device_t *dev);
 extern int drm_bo_ioctl(DRM_IOCTL_ARGS);
 extern int drm_mm_init_ioctl(DRM_IOCTL_ARGS);
 extern int drm_bo_clean_mm(drm_device_t *dev);
+extern int drm_fence_buffer_objects(drm_file_t * priv,
+                                   struct list_head *list, 
+                                   drm_fence_object_t *fence,
+                                   drm_fence_object_t **used_fence);
 
 
 /* Inline replacements for DRM_IOREMAP macros */
 
 
 /* Inline replacements for DRM_IOREMAP macros */
index 1f0bbba..68af5c3 100644 (file)
@@ -199,8 +199,15 @@ void drm_bo_usage_deref_unlocked(drm_device_t * dev, drm_buffer_object_t * bo)
        }
 }
 
        }
 }
 
+/*
+ * Note. The caller has to register (if applicable) 
+ * and deregister fence object usage.
+ */
+
 int drm_fence_buffer_objects(drm_file_t * priv,
 int drm_fence_buffer_objects(drm_file_t * priv,
-                            struct list_head *list, drm_fence_object_t * fence)
+                            struct list_head *list, 
+                            drm_fence_object_t *fence,
+                            drm_fence_object_t **used_fence)
 {
        drm_device_t *dev = priv->head->dev;
        drm_buffer_manager_t *bm = &dev->bm;
 {
        drm_device_t *dev = priv->head->dev;
        drm_buffer_manager_t *bm = &dev->bm;
@@ -230,19 +237,9 @@ int drm_fence_buffer_objects(drm_file_t * priv,
                        goto out;
                }
        } else {
                        goto out;
                }
        } else {
-               fence = kmem_cache_alloc(drm_cache.fence_object, GFP_KERNEL);
-
-               if (!fence) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-
-               ret = drm_fence_object_init(dev, fence_flags, 1, fence);
-
-               if (ret) {
-                       kmem_cache_free(drm_cache.fence_object, fence);
-                       goto out;
-               }
+               ret = drm_fence_object_create(dev, fence_flags, 1, &fence);
+               if (ret)
+                       goto out;               
        }
 
        /*
        }
 
        /*
@@ -285,14 +282,14 @@ int drm_fence_buffer_objects(drm_file_t * priv,
                drm_bo_usage_deref_locked(dev, entry);
                l = f_list.next;
        }
                drm_bo_usage_deref_locked(dev, entry);
                l = f_list.next;
        }
-       if (!count)
-               drm_fence_usage_deref_locked(dev, fence);
-       else if (count > 1)
-               atomic_add(count - 1, &fence->usage);
+       atomic_add(count, &fence->usage);
       out:
        mutex_unlock(&dev->struct_mutex);
       out:
        mutex_unlock(&dev->struct_mutex);
+       *used_fence = fence;
        return ret;
 }
        return ret;
 }
+EXPORT_SYMBOL(drm_fence_buffer_objects);
+
 
 /*
  * Call bo->mutex locked.
 
 /*
  * Call bo->mutex locked.
index 1deeaaa..fd43d8b 100644 (file)
@@ -417,14 +417,28 @@ int drm_fence_object_init(drm_device_t * dev, uint32_t type, int emit,
 
 EXPORT_SYMBOL(drm_fence_object_init);
 
 
 EXPORT_SYMBOL(drm_fence_object_init);
 
-static int drm_fence_object_create(drm_file_t * priv, uint32_t type,
-                                  int emit, int shareable,
-                                  uint32_t * user_handle,
-                                  drm_fence_object_t ** c_fence)
+int drm_fence_add_user_object(drm_file_t *priv, drm_fence_object_t *fence,
+                             int shareable)
 {
        drm_device_t *dev = priv->head->dev;
        int ret;
 {
        drm_device_t *dev = priv->head->dev;
        int ret;
+
+       mutex_lock(&dev->struct_mutex);
+       ret = drm_add_user_object(priv, &fence->base, shareable);
+       mutex_unlock(&dev->struct_mutex);
+       if (ret)
+               return ret;
+       fence->base.type = drm_fence_type;
+       fence->base.remove = &drm_fence_object_destroy;
+       return 0;
+}
+EXPORT_SYMBOL(drm_fence_add_user_object);
+
+int drm_fence_object_create(drm_device_t *dev, uint32_t type,
+                           int emit, drm_fence_object_t **c_fence)
+{
        drm_fence_object_t *fence;
        drm_fence_object_t *fence;
+       int ret;
 
        fence = kmem_cache_alloc(drm_cache.fence_object, GFP_KERNEL);
        if (!fence)
 
        fence = kmem_cache_alloc(drm_cache.fence_object, GFP_KERNEL);
        if (!fence)
@@ -434,23 +448,11 @@ static int drm_fence_object_create(drm_file_t * priv, uint32_t type,
                drm_fence_usage_deref_unlocked(dev, fence);
                return ret;
        }
                drm_fence_usage_deref_unlocked(dev, fence);
                return ret;
        }
-
-       mutex_lock(&dev->struct_mutex);
-       ret = drm_add_user_object(priv, &fence->base, shareable);
-       mutex_unlock(&dev->struct_mutex);
-       if (ret) {
-               drm_fence_usage_deref_unlocked(dev, fence);
-               *c_fence = NULL;
-               *user_handle = 0;
-               return ret;
-       }
-       fence->base.type = drm_fence_type;
-       fence->base.remove = &drm_fence_object_destroy;
-       *user_handle = fence->base.hash.key;
-       *c_fence = fence;
-
+       *c_fence = fence; 
        return 0;
 }
        return 0;
 }
+EXPORT_SYMBOL(drm_fence_object_create);
+
 
 void drm_fence_manager_init(drm_device_t * dev)
 {
 
 void drm_fence_manager_init(drm_device_t * dev)
 {
@@ -511,24 +513,29 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS)
 
        DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
        switch (arg.op) {
 
        DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
        switch (arg.op) {
-       case drm_fence_create:{
-                       int emit = arg.flags & DRM_FENCE_FLAG_EMIT;
-                       if (emit)
-                               LOCK_TEST_WITH_RETURN(dev, filp);
-                       ret =
-                           drm_fence_object_create(priv, arg.type,
-                                                   emit,
-                                                   arg.
-                                                   flags &
-                                                   DRM_FENCE_FLAG_SHAREABLE,
-                                                   &arg.handle, &fence);
-                       if (ret)
-                               return ret;
-                       mutex_lock(&dev->struct_mutex);
-                       atomic_inc(&fence->usage);
-                       mutex_unlock(&dev->struct_mutex);
-                       break;
+       case drm_fence_create:
+               if (arg.flags & DRM_FENCE_FLAG_EMIT)
+                       LOCK_TEST_WITH_RETURN(dev, filp);
+               ret = drm_fence_object_create(dev, arg.type,
+                                             arg.flags & DRM_FENCE_FLAG_EMIT,
+                                             &fence);
+               if (ret)
+                       return ret;
+               ret = drm_fence_add_user_object(priv, fence, 
+                                               arg.flags & 
+                                               DRM_FENCE_FLAG_SHAREABLE);
+               if (ret) {
+                       drm_fence_usage_deref_unlocked(dev, fence);
+                       return ret;
                }
                }
+
+               /*
+                * usage > 0. No need to lock dev->struct_mutex;
+                */
+
+               atomic_inc(&fence->usage);
+               arg.handle = fence->base.hash.key;
+               break;
        case drm_fence_destroy:
                mutex_lock(&dev->struct_mutex);
                uo = drm_lookup_user_object(priv, arg.handle);
        case drm_fence_destroy:
                mutex_lock(&dev->struct_mutex);
                uo = drm_lookup_user_object(priv, arg.handle);
@@ -577,6 +584,23 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS)
                        return -EINVAL;
                ret = drm_fence_object_emit(dev, fence, arg.type);
                break;
                        return -EINVAL;
                ret = drm_fence_object_emit(dev, fence, arg.type);
                break;
+       case drm_fence_buffers:
+               if (!dev->bm.initialized) {
+                       DRM_ERROR("Buffer object manager is not initialized\n");
+                       return -EINVAL;
+               }
+               LOCK_TEST_WITH_RETURN(dev, filp);
+               ret = drm_fence_buffer_objects(priv, NULL, NULL, &fence);
+               if (ret) 
+                       return ret;
+               ret = drm_fence_add_user_object(priv, fence, 
+                                               arg.flags & 
+                                               DRM_FENCE_FLAG_SHAREABLE);
+               if (ret)
+                       return ret;
+               atomic_inc(&fence->usage);
+               arg.handle = fence->base.hash.key;
+               break;                  
        default:
                return -EINVAL;
        }
        default:
                return -EINVAL;
        }
index 1a43e0a..e39f888 100644 (file)
@@ -659,7 +659,8 @@ typedef struct drm_fence_arg {
                drm_fence_signaled,
                drm_fence_flush,
                drm_fence_wait,
                drm_fence_signaled,
                drm_fence_flush,
                drm_fence_wait,
-               drm_fence_emit
+               drm_fence_emit,
+               drm_fence_buffers
        } op;
 } drm_fence_arg_t;
 
        } op;
 } drm_fence_arg_t;