aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorJason Ekstrand <jason@jlekstrand.net>2017-08-25 13:52:25 -0400
committerDave Airlie <airlied@redhat.com>2017-08-28 16:27:41 -0400
commit1fc08218ed2a42c86af5c905fe4c00885376a07e (patch)
treed143951efc18fe4669a2944916d07204e9460f4b /drivers/gpu/drm
parent9c19fb10a5893d6501df4d0fb93d954d5fc1d91b (diff)
drm/syncobj: Add a CREATE_SIGNALED flag
This requests that the driver create the sync object such that it already has a signaled dma_fence attached. Because we don't need anything in particular (just something signaled), we use a dummy null fence. This is useful for Vulkan which has a similar flag that can be passed to vkCreateFence. Signed-off-by: Jason Ekstrand <jason@jlekstrand.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/drm_syncobj.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index bade497b3f1d..12db8c9564cd 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -154,6 +154,49 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
154} 154}
155EXPORT_SYMBOL(drm_syncobj_replace_fence); 155EXPORT_SYMBOL(drm_syncobj_replace_fence);
156 156
157struct drm_syncobj_null_fence {
158 struct dma_fence base;
159 spinlock_t lock;
160};
161
162static const char *drm_syncobj_null_fence_get_name(struct dma_fence *fence)
163{
164 return "syncobjnull";
165}
166
167static bool drm_syncobj_null_fence_enable_signaling(struct dma_fence *fence)
168{
169 dma_fence_enable_sw_signaling(fence);
170 return !dma_fence_is_signaled(fence);
171}
172
173static const struct dma_fence_ops drm_syncobj_null_fence_ops = {
174 .get_driver_name = drm_syncobj_null_fence_get_name,
175 .get_timeline_name = drm_syncobj_null_fence_get_name,
176 .enable_signaling = drm_syncobj_null_fence_enable_signaling,
177 .wait = dma_fence_default_wait,
178 .release = NULL,
179};
180
181static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
182{
183 struct drm_syncobj_null_fence *fence;
184 fence = kzalloc(sizeof(*fence), GFP_KERNEL);
185 if (fence == NULL)
186 return -ENOMEM;
187
188 spin_lock_init(&fence->lock);
189 dma_fence_init(&fence->base, &drm_syncobj_null_fence_ops,
190 &fence->lock, 0, 0);
191 dma_fence_signal(&fence->base);
192
193 drm_syncobj_replace_fence(syncobj, &fence->base);
194
195 dma_fence_put(&fence->base);
196
197 return 0;
198}
199
157int drm_syncobj_find_fence(struct drm_file *file_private, 200int drm_syncobj_find_fence(struct drm_file *file_private,
158 u32 handle, 201 u32 handle,
159 struct dma_fence **fence) 202 struct dma_fence **fence)
@@ -190,7 +233,7 @@ void drm_syncobj_free(struct kref *kref)
190EXPORT_SYMBOL(drm_syncobj_free); 233EXPORT_SYMBOL(drm_syncobj_free);
191 234
192static int drm_syncobj_create(struct drm_file *file_private, 235static int drm_syncobj_create(struct drm_file *file_private,
193 u32 *handle) 236 u32 *handle, uint32_t flags)
194{ 237{
195 int ret; 238 int ret;
196 struct drm_syncobj *syncobj; 239 struct drm_syncobj *syncobj;
@@ -203,6 +246,14 @@ static int drm_syncobj_create(struct drm_file *file_private,
203 INIT_LIST_HEAD(&syncobj->cb_list); 246 INIT_LIST_HEAD(&syncobj->cb_list);
204 spin_lock_init(&syncobj->lock); 247 spin_lock_init(&syncobj->lock);
205 248
249 if (flags & DRM_SYNCOBJ_CREATE_SIGNALED) {
250 ret = drm_syncobj_assign_null_handle(syncobj);
251 if (ret < 0) {
252 drm_syncobj_put(syncobj);
253 return ret;
254 }
255 }
256
206 idr_preload(GFP_KERNEL); 257 idr_preload(GFP_KERNEL);
207 spin_lock(&file_private->syncobj_table_lock); 258 spin_lock(&file_private->syncobj_table_lock);
208 ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT); 259 ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT);
@@ -438,11 +489,11 @@ drm_syncobj_create_ioctl(struct drm_device *dev, void *data,
438 return -ENODEV; 489 return -ENODEV;
439 490
440 /* no valid flags yet */ 491 /* no valid flags yet */
441 if (args->flags) 492 if (args->flags & ~DRM_SYNCOBJ_CREATE_SIGNALED)
442 return -EINVAL; 493 return -EINVAL;
443 494
444 return drm_syncobj_create(file_private, 495 return drm_syncobj_create(file_private,
445 &args->handle); 496 &args->handle, args->flags);
446} 497}
447 498
448int 499int