27
27
#include <drm/drm_damage_helper.h>
28
28
#include <drm/drm_fourcc.h>
29
29
#include <drm/drm_gem_atomic_helper.h>
30
+ #include <linux/virtio_dma_buf.h>
30
31
31
32
#include "virtgpu_drv.h"
32
33
@@ -259,6 +260,44 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane,
259
260
rect .y2 - rect .y1 );
260
261
}
261
262
263
+ static int virtio_gpu_prepare_imported_obj (struct drm_plane * plane ,
264
+ struct drm_plane_state * new_state ,
265
+ struct drm_gem_object * obj )
266
+ {
267
+ struct virtio_gpu_device * vgdev = plane -> dev -> dev_private ;
268
+ struct virtio_gpu_object * bo = gem_to_virtio_gpu_obj (obj );
269
+ struct dma_buf_attachment * attach = obj -> import_attach ;
270
+ struct dma_resv * resv = attach -> dmabuf -> resv ;
271
+ struct virtio_gpu_mem_entry * ents = NULL ;
272
+ unsigned int nents ;
273
+ int ret ;
274
+
275
+ dma_resv_lock (resv , NULL );
276
+
277
+ ret = dma_buf_pin (attach );
278
+ if (ret ) {
279
+ dma_resv_unlock (resv );
280
+ return ret ;
281
+ }
282
+
283
+ if (!bo -> sgt ) {
284
+ ret = virtgpu_dma_buf_import_sgt (& ents , & nents ,
285
+ bo , attach );
286
+ if (ret )
287
+ goto err ;
288
+
289
+ virtio_gpu_object_attach (vgdev , bo , ents , nents );
290
+ }
291
+
292
+ dma_resv_unlock (resv );
293
+ return 0 ;
294
+
295
+ err :
296
+ dma_buf_unpin (attach );
297
+ dma_resv_unlock (resv );
298
+ return ret ;
299
+ }
300
+
262
301
static int virtio_gpu_plane_prepare_fb (struct drm_plane * plane ,
263
302
struct drm_plane_state * new_state )
264
303
{
@@ -267,6 +306,8 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane,
267
306
struct virtio_gpu_framebuffer * vgfb ;
268
307
struct virtio_gpu_plane_state * vgplane_st ;
269
308
struct virtio_gpu_object * bo ;
309
+ struct drm_gem_object * obj ;
310
+ int ret ;
270
311
271
312
if (!new_state -> fb )
272
313
return 0 ;
@@ -280,7 +321,14 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane,
280
321
if (!bo || (plane -> type == DRM_PLANE_TYPE_PRIMARY && !bo -> guest_blob ))
281
322
return 0 ;
282
323
283
- if (bo -> dumb ) {
324
+ obj = new_state -> fb -> obj [0 ];
325
+ if (obj -> import_attach ) {
326
+ ret = virtio_gpu_prepare_imported_obj (plane , new_state , obj );
327
+ if (ret )
328
+ return ret ;
329
+ }
330
+
331
+ if (bo -> dumb || obj -> import_attach ) {
284
332
vgplane_st -> fence = virtio_gpu_fence_alloc (vgdev ,
285
333
vgdev -> fence_drv .context ,
286
334
0 );
@@ -291,10 +339,21 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane,
291
339
return 0 ;
292
340
}
293
341
342
+ static void virtio_gpu_cleanup_imported_obj (struct drm_gem_object * obj )
343
+ {
344
+ struct dma_buf_attachment * attach = obj -> import_attach ;
345
+ struct dma_resv * resv = attach -> dmabuf -> resv ;
346
+
347
+ dma_resv_lock (resv , NULL );
348
+ dma_buf_unpin (attach );
349
+ dma_resv_unlock (resv );
350
+ }
351
+
294
352
static void virtio_gpu_plane_cleanup_fb (struct drm_plane * plane ,
295
353
struct drm_plane_state * state )
296
354
{
297
355
struct virtio_gpu_plane_state * vgplane_st ;
356
+ struct drm_gem_object * obj ;
298
357
299
358
if (!state -> fb )
300
359
return ;
@@ -304,6 +363,10 @@ static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane,
304
363
dma_fence_put (& vgplane_st -> fence -> f );
305
364
vgplane_st -> fence = NULL ;
306
365
}
366
+
367
+ obj = state -> fb -> obj [0 ];
368
+ if (obj -> import_attach )
369
+ virtio_gpu_cleanup_imported_obj (obj );
307
370
}
308
371
309
372
static void virtio_gpu_cursor_plane_update (struct drm_plane * plane ,
0 commit comments