@@ -3409,6 +3409,130 @@ static int vulkan_map_from_vaapi(AVHWFramesContext *dst_fc,
3409
3409
#endif
3410
3410
3411
3411
#if CONFIG_CUDA
3412
+ static int export_mem_to_cuda (AVHWDeviceContext * ctx ,
3413
+ AVHWDeviceContext * cuda_cu , CudaFunctions * cu ,
3414
+ AVVkFrameInternal * dst_int , int idx ,
3415
+ VkDeviceMemory mem , size_t size )
3416
+ {
3417
+ VkResult ret ;
3418
+ VulkanDevicePriv * p = ctx -> hwctx ;
3419
+ AVVulkanDeviceContext * hwctx = & p -> p ;
3420
+ FFVulkanFunctions * vk = & p -> vkctx .vkfn ;
3421
+
3422
+ #ifdef _WIN32
3423
+ CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3424
+ .type = IsWindows8OrGreater ()
3425
+ ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
3426
+ : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT ,
3427
+ .size = size ,
3428
+ };
3429
+ VkMemoryGetWin32HandleInfoKHR export_info = {
3430
+ .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR ,
3431
+ .memory = mem ,
3432
+ .handleType = IsWindows8OrGreater ()
3433
+ ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
3434
+ : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT ,
3435
+ };
3436
+
3437
+ ret = vk -> GetMemoryWin32HandleKHR (hwctx -> act_dev , & export_info ,
3438
+ & ext_desc .handle .win32 .handle );
3439
+ if (ret != VK_SUCCESS ) {
3440
+ av_log (ctx , AV_LOG_ERROR , "Unable to export the image as a Win32 Handle: %s!\n" ,
3441
+ ff_vk_ret2str (ret ));
3442
+ return AVERROR_EXTERNAL ;
3443
+ }
3444
+ dst_int -> ext_mem_handle [idx ] = ext_desc .handle .win32 .handle ;
3445
+ #else
3446
+ CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3447
+ .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD ,
3448
+ .size = size ,
3449
+ };
3450
+ VkMemoryGetFdInfoKHR export_info = {
3451
+ .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR ,
3452
+ .memory = mem ,
3453
+ .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR ,
3454
+ };
3455
+
3456
+ ret = vk -> GetMemoryFdKHR (hwctx -> act_dev , & export_info ,
3457
+ & ext_desc .handle .fd );
3458
+ if (ret != VK_SUCCESS ) {
3459
+ av_log (ctx , AV_LOG_ERROR , "Unable to export the image as a FD: %s!\n" ,
3460
+ ff_vk_ret2str (ret ));
3461
+ return AVERROR_EXTERNAL ;
3462
+ }
3463
+ #endif
3464
+
3465
+ ret = CHECK_CU (cu -> cuImportExternalMemory (& dst_int -> ext_mem [idx ], & ext_desc ));
3466
+ if (ret < 0 ) {
3467
+ #ifndef _WIN32
3468
+ close (ext_desc .handle .fd );
3469
+ #endif
3470
+ return AVERROR_EXTERNAL ;
3471
+ }
3472
+
3473
+ return 0 ;
3474
+ }
3475
+
3476
+ static int export_sem_to_cuda (AVHWDeviceContext * ctx ,
3477
+ AVHWDeviceContext * cuda_cu , CudaFunctions * cu ,
3478
+ AVVkFrameInternal * dst_int , int idx ,
3479
+ VkSemaphore sem )
3480
+ {
3481
+ VkResult ret ;
3482
+ VulkanDevicePriv * p = ctx -> hwctx ;
3483
+ AVVulkanDeviceContext * hwctx = & p -> p ;
3484
+ FFVulkanFunctions * vk = & p -> vkctx .vkfn ;
3485
+
3486
+ #ifdef _WIN32
3487
+ VkSemaphoreGetWin32HandleInfoKHR sem_export = {
3488
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR ,
3489
+ .semaphore = sem ,
3490
+ .handleType = IsWindows8OrGreater ()
3491
+ ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
3492
+ : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT ,
3493
+ };
3494
+ CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3495
+ .type = 10 /* TODO: CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_WIN32 */ ,
3496
+ };
3497
+ #else
3498
+ VkSemaphoreGetFdInfoKHR sem_export = {
3499
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR ,
3500
+ .semaphore = sem ,
3501
+ .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT ,
3502
+ };
3503
+ CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3504
+ .type = 9 /* TODO: CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FD */ ,
3505
+ };
3506
+ #endif
3507
+
3508
+ #ifdef _WIN32
3509
+ ret = vk -> GetSemaphoreWin32HandleKHR (hwctx -> act_dev , & sem_export ,
3510
+ & ext_sem_desc .handle .win32 .handle );
3511
+ #else
3512
+ ret = vk -> GetSemaphoreFdKHR (hwctx -> act_dev , & sem_export ,
3513
+ & ext_sem_desc .handle .fd );
3514
+ #endif
3515
+ if (ret != VK_SUCCESS ) {
3516
+ av_log (ctx , AV_LOG_ERROR , "Failed to export semaphore: %s\n" ,
3517
+ ff_vk_ret2str (ret ));
3518
+ return AVERROR_EXTERNAL ;
3519
+ }
3520
+ #ifdef _WIN32
3521
+ dst_int -> ext_sem_handle [idx ] = ext_sem_desc .handle .win32 .handle ;
3522
+ #endif
3523
+
3524
+ ret = CHECK_CU (cu -> cuImportExternalSemaphore (& dst_int -> cu_sem [idx ],
3525
+ & ext_sem_desc ));
3526
+ if (ret < 0 ) {
3527
+ #ifndef _WIN32
3528
+ close (ext_sem_desc .handle .fd );
3529
+ #endif
3530
+ return AVERROR_EXTERNAL ;
3531
+ }
3532
+
3533
+ return 0 ;
3534
+ }
3535
+
3412
3536
static int vulkan_export_to_cuda (AVHWFramesContext * hwfc ,
3413
3537
AVBufferRef * cuda_hwfc ,
3414
3538
const AVFrame * frame )
@@ -3423,6 +3547,7 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
3423
3547
VulkanDevicePriv * p = ctx -> hwctx ;
3424
3548
AVVulkanDeviceContext * hwctx = & p -> p ;
3425
3549
FFVulkanFunctions * vk = & p -> vkctx .vkfn ;
3550
+ int nb_images ;
3426
3551
3427
3552
AVHWFramesContext * cuda_fc = (AVHWFramesContext * )cuda_hwfc -> data ;
3428
3553
AVHWDeviceContext * cuda_cu = cuda_fc -> device_ctx ;
@@ -3436,13 +3561,42 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
3436
3561
dst_int = dst_f -> internal ;
3437
3562
3438
3563
if (!dst_int -> cuda_fc_ref ) {
3564
+ size_t offsets [3 ] = { 0 };
3565
+
3439
3566
dst_int -> cuda_fc_ref = av_buffer_ref (cuda_hwfc );
3440
3567
if (!dst_int -> cuda_fc_ref )
3441
3568
return AVERROR (ENOMEM );
3442
3569
3570
+ nb_images = ff_vk_count_images (dst_f );
3571
+ for (int i = 0 ; i < nb_images ; i ++ ) {
3572
+ err = export_mem_to_cuda (ctx , cuda_cu , cu , dst_int , i ,
3573
+ dst_f -> mem [i ], dst_f -> size [i ]);
3574
+ if (err < 0 )
3575
+ goto fail ;
3576
+
3577
+ err = export_sem_to_cuda (ctx , cuda_cu , cu , dst_int , i ,
3578
+ dst_f -> sem [i ]);
3579
+ if (err < 0 )
3580
+ goto fail ;
3581
+ }
3582
+
3583
+ if (nb_images != planes ) {
3584
+ for (int i = 0 ; i < planes ; i ++ ) {
3585
+ VkImageSubresource subres = {
3586
+ .aspectMask = i == 2 ? VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT :
3587
+ i == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3588
+ VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT
3589
+ };
3590
+ VkSubresourceLayout layout = { 0 };
3591
+ vk -> GetImageSubresourceLayout (hwctx -> act_dev , dst_f -> img [FFMIN (i , nb_images - 1 )],
3592
+ & subres , & layout );
3593
+ offsets [i ] = layout .offset ;
3594
+ }
3595
+ }
3596
+
3443
3597
for (int i = 0 ; i < planes ; i ++ ) {
3444
3598
CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = {
3445
- .offset = 0 ,
3599
+ .offset = offsets [ i ] ,
3446
3600
.arrayDesc = {
3447
3601
.Depth = 0 ,
3448
3602
.Format = cufmt ,
@@ -3453,84 +3607,12 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
3453
3607
};
3454
3608
int p_w , p_h ;
3455
3609
3456
- #ifdef _WIN32
3457
- CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3458
- .type = IsWindows8OrGreater ()
3459
- ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
3460
- : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT ,
3461
- .size = dst_f -> size [i ],
3462
- };
3463
- VkMemoryGetWin32HandleInfoKHR export_info = {
3464
- .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR ,
3465
- .memory = dst_f -> mem [i ],
3466
- .handleType = IsWindows8OrGreater ()
3467
- ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
3468
- : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT ,
3469
- };
3470
- VkSemaphoreGetWin32HandleInfoKHR sem_export = {
3471
- .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR ,
3472
- .semaphore = dst_f -> sem [i ],
3473
- .handleType = IsWindows8OrGreater ()
3474
- ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
3475
- : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT ,
3476
- };
3477
- CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3478
- .type = 10 /* TODO: CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_WIN32 */ ,
3479
- };
3480
-
3481
- ret = vk -> GetMemoryWin32HandleKHR (hwctx -> act_dev , & export_info ,
3482
- & ext_desc .handle .win32 .handle );
3483
- if (ret != VK_SUCCESS ) {
3484
- av_log (hwfc , AV_LOG_ERROR , "Unable to export the image as a Win32 Handle: %s!\n" ,
3485
- ff_vk_ret2str (ret ));
3486
- err = AVERROR_EXTERNAL ;
3487
- goto fail ;
3488
- }
3489
- dst_int -> ext_mem_handle [i ] = ext_desc .handle .win32 .handle ;
3490
- #else
3491
- CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3492
- .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD ,
3493
- .size = dst_f -> size [i ],
3494
- };
3495
- VkMemoryGetFdInfoKHR export_info = {
3496
- .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR ,
3497
- .memory = dst_f -> mem [i ],
3498
- .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR ,
3499
- };
3500
- VkSemaphoreGetFdInfoKHR sem_export = {
3501
- .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR ,
3502
- .semaphore = dst_f -> sem [i ],
3503
- .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT ,
3504
- };
3505
- CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3506
- .type = 9 /* TODO: CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FD */ ,
3507
- };
3508
-
3509
- ret = vk -> GetMemoryFdKHR (hwctx -> act_dev , & export_info ,
3510
- & ext_desc .handle .fd );
3511
- if (ret != VK_SUCCESS ) {
3512
- av_log (hwfc , AV_LOG_ERROR , "Unable to export the image as a FD: %s!\n" ,
3513
- ff_vk_ret2str (ret ));
3514
- err = AVERROR_EXTERNAL ;
3515
- goto fail ;
3516
- }
3517
- #endif
3518
-
3519
- ret = CHECK_CU (cu -> cuImportExternalMemory (& dst_int -> ext_mem [i ], & ext_desc ));
3520
- if (ret < 0 ) {
3521
- #ifndef _WIN32
3522
- close (ext_desc .handle .fd );
3523
- #endif
3524
- err = AVERROR_EXTERNAL ;
3525
- goto fail ;
3526
- }
3527
-
3528
3610
get_plane_wh (& p_w , & p_h , hwfc -> sw_format , hwfc -> width , hwfc -> height , i );
3529
3611
tex_desc .arrayDesc .Width = p_w ;
3530
3612
tex_desc .arrayDesc .Height = p_h ;
3531
3613
3532
3614
ret = CHECK_CU (cu -> cuExternalMemoryGetMappedMipmappedArray (& dst_int -> cu_mma [i ],
3533
- dst_int -> ext_mem [i ],
3615
+ dst_int -> ext_mem [FFMIN ( i , nb_images - 1 ) ],
3534
3616
& tex_desc ));
3535
3617
if (ret < 0 ) {
3536
3618
err = AVERROR_EXTERNAL ;
@@ -3544,32 +3626,6 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
3544
3626
goto fail ;
3545
3627
}
3546
3628
3547
- #ifdef _WIN32
3548
- ret = vk -> GetSemaphoreWin32HandleKHR (hwctx -> act_dev , & sem_export ,
3549
- & ext_sem_desc .handle .win32 .handle );
3550
- #else
3551
- ret = vk -> GetSemaphoreFdKHR (hwctx -> act_dev , & sem_export ,
3552
- & ext_sem_desc .handle .fd );
3553
- #endif
3554
- if (ret != VK_SUCCESS ) {
3555
- av_log (ctx , AV_LOG_ERROR , "Failed to export semaphore: %s\n" ,
3556
- ff_vk_ret2str (ret ));
3557
- err = AVERROR_EXTERNAL ;
3558
- goto fail ;
3559
- }
3560
- #ifdef _WIN32
3561
- dst_int -> ext_sem_handle [i ] = ext_sem_desc .handle .win32 .handle ;
3562
- #endif
3563
-
3564
- ret = CHECK_CU (cu -> cuImportExternalSemaphore (& dst_int -> cu_sem [i ],
3565
- & ext_sem_desc ));
3566
- if (ret < 0 ) {
3567
- #ifndef _WIN32
3568
- close (ext_sem_desc .handle .fd );
3569
- #endif
3570
- err = AVERROR_EXTERNAL ;
3571
- goto fail ;
3572
- }
3573
3629
}
3574
3630
}
3575
3631
@@ -4313,6 +4369,7 @@ static int vulkan_transfer_data_to_cuda(AVHWFramesContext *hwfc, AVFrame *dst,
4313
4369
VulkanFramesPriv * fp = hwfc -> hwctx ;
4314
4370
const int planes = av_pix_fmt_count_planes (hwfc -> sw_format );
4315
4371
const AVPixFmtDescriptor * desc = av_pix_fmt_desc_get (hwfc -> sw_format );
4372
+ int nb_images ;
4316
4373
4317
4374
AVHWFramesContext * cuda_fc = (AVHWFramesContext * )dst -> hw_frames_ctx -> data ;
4318
4375
AVHWDeviceContext * cuda_cu = cuda_fc -> device_ctx ;
@@ -4323,6 +4380,7 @@ static int vulkan_transfer_data_to_cuda(AVHWFramesContext *hwfc, AVFrame *dst,
4323
4380
CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS s_s_par [AV_NUM_DATA_POINTERS ] = { 0 };
4324
4381
4325
4382
dst_f = (AVVkFrame * )src -> data [0 ];
4383
+ nb_images = ff_vk_count_images (dst_f );
4326
4384
4327
4385
err = prepare_frame (hwfc , & fp -> upload_exec , dst_f , PREP_MODE_EXTERNAL_EXPORT );
4328
4386
if (err < 0 )
@@ -4346,7 +4404,7 @@ static int vulkan_transfer_data_to_cuda(AVHWFramesContext *hwfc, AVFrame *dst,
4346
4404
}
4347
4405
4348
4406
err = CHECK_CU (cu -> cuWaitExternalSemaphoresAsync (dst_int -> cu_sem , s_w_par ,
4349
- planes , cuda_dev -> stream ));
4407
+ nb_images , cuda_dev -> stream ));
4350
4408
if (err < 0 )
4351
4409
goto fail ;
4352
4410
@@ -4373,7 +4431,7 @@ static int vulkan_transfer_data_to_cuda(AVHWFramesContext *hwfc, AVFrame *dst,
4373
4431
}
4374
4432
4375
4433
err = CHECK_CU (cu -> cuSignalExternalSemaphoresAsync (dst_int -> cu_sem , s_s_par ,
4376
- planes , cuda_dev -> stream ));
4434
+ nb_images , cuda_dev -> stream ));
4377
4435
if (err < 0 )
4378
4436
goto fail ;
4379
4437
0 commit comments