21 #define VK_NO_PROTOTYPES
22 #define VK_ENABLE_BETA_EXTENSIONS
26 #include <versionhelpers.h>
53 #include <va/va_drmcommon.h>
56 #include <sys/sysmacros.h>
60 #include <drm_fourcc.h>
64 #if HAVE_LINUX_DMA_BUF_H
65 #include <sys/ioctl.h>
66 #include <linux/dma-buf.h>
72 #define CHECK_CU(x) FF_CUDA_CHECK_DL(cuda_cu, cu, x)
89 VkPhysicalDeviceProperties2
props;
90 VkPhysicalDeviceMemoryProperties
mprops;
91 VkPhysicalDeviceExternalMemoryHostPropertiesEXT
hprops;
164 #define ASPECT_2PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT)
165 #define ASPECT_3PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)
177 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_GRAY8, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8_UNORM } },
178 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
179 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GRAYF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_SFLOAT } },
182 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_XV36, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
183 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_BGRA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
184 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGBA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
185 { VK_FORMAT_R8G8B8_UNORM,
AV_PIX_FMT_RGB24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8_UNORM } },
186 { VK_FORMAT_B8G8R8_UNORM,
AV_PIX_FMT_BGR24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8_UNORM } },
187 { VK_FORMAT_R16G16B16_UNORM,
AV_PIX_FMT_RGB48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16_UNORM } },
188 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_RGBA64, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
189 { VK_FORMAT_R5G6B5_UNORM_PACK16,
AV_PIX_FMT_RGB565, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R5G6B5_UNORM_PACK16 } },
190 { VK_FORMAT_B5G6R5_UNORM_PACK16,
AV_PIX_FMT_BGR565, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B5G6R5_UNORM_PACK16 } },
191 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_BGR0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
192 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGB0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
193 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_X2RGB10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
194 { VK_FORMAT_A2B10G10R10_UNORM_PACK32,
AV_PIX_FMT_X2BGR10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2B10G10R10_UNORM_PACK32 } },
197 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_GBRAP, VK_IMAGE_ASPECT_COLOR_BIT, 1, 4, 4, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } },
198 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GBRAP16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
199 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GBRPF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 3, 3, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } },
200 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GBRAPF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 4, 4, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } },
204 { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
AV_PIX_FMT_P010,
ASPECT_2PLANE, 2, 1, 2, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM } },
205 { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
AV_PIX_FMT_P012,
ASPECT_2PLANE, 2, 1, 2, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM } },
210 { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
AV_PIX_FMT_P210,
ASPECT_2PLANE, 2, 1, 2, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM } },
211 { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
AV_PIX_FMT_P212,
ASPECT_2PLANE, 2, 1, 2, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM } },
216 { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16,
AV_PIX_FMT_P410,
ASPECT_2PLANE, 2, 1, 2, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM } },
217 { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16,
AV_PIX_FMT_P412,
ASPECT_2PLANE, 2, 1, 2, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM } },
235 { VK_FORMAT_G8B8G8R8_422_UNORM,
AV_PIX_FMT_YUYV422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
236 { VK_FORMAT_B8G8R8G8_422_UNORM,
AV_PIX_FMT_UYVY422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
237 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
AV_PIX_FMT_Y210, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
238 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
AV_PIX_FMT_Y212, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
259 #define FN_MAP_TO(dst_t, dst_name, src_t, src_name) \
260 static av_unused dst_t map_ ##src_name## _to_ ##dst_name(src_t src) \
263 MAP_TO(VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT, \
264 VK_IMAGE_USAGE_SAMPLED_BIT); \
265 MAP_TO(VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT, \
266 VK_IMAGE_USAGE_TRANSFER_SRC_BIT); \
267 MAP_TO(VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT, \
268 VK_IMAGE_USAGE_TRANSFER_DST_BIT); \
269 MAP_TO(VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT, \
270 VK_IMAGE_USAGE_STORAGE_BIT); \
271 MAP_TO(VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT, \
272 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); \
273 MAP_TO(VK_FORMAT_FEATURE_2_VIDEO_DECODE_OUTPUT_BIT_KHR, \
274 VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR); \
275 MAP_TO(VK_FORMAT_FEATURE_2_VIDEO_DECODE_DPB_BIT_KHR, \
276 VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR); \
277 MAP_TO(VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR, \
278 VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR); \
279 MAP_TO(VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR, \
280 VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR); \
284 #define MAP_TO(flag1, flag2) if (src & flag2) dst |= flag1;
285 FN_MAP_TO(VkFormatFeatureFlagBits2, feats, VkImageUsageFlags,
usage)
287 #define MAP_TO(flag1, flag2) if (src & flag1) dst |= flag2;
288 FN_MAP_TO(VkImageUsageFlags,
usage, VkFormatFeatureFlagBits2, feats)
293 VkImageTiling tiling,
296 VkImageAspectFlags *
aspect,
297 VkImageUsageFlags *supported_usage,
298 int disable_multiplane,
int need_storage)
304 const VkFormatFeatureFlagBits2 basic_flags = VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
305 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
306 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
310 VkFormatProperties3 fprops = {
311 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3,
313 VkFormatProperties2 prop = {
314 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
317 VkFormatFeatureFlagBits2 feats_primary, feats_secondary;
318 int basics_primary = 0, basics_secondary = 0;
319 int storage_primary = 0, storage_secondary = 0;
321 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
325 feats_primary = tiling == VK_IMAGE_TILING_LINEAR ?
326 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
327 basics_primary = (feats_primary & basic_flags) == basic_flags;
328 storage_primary = !!(feats_primary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
331 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
334 feats_secondary = tiling == VK_IMAGE_TILING_LINEAR ?
335 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
336 basics_secondary = (feats_secondary & basic_flags) == basic_flags;
337 storage_secondary = !!(feats_secondary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
339 basics_secondary = basics_primary;
340 storage_secondary = storage_primary;
343 if (basics_primary &&
345 (!need_storage || (need_storage && (storage_primary | storage_secondary)))) {
353 *supported_usage = map_feats_to_usage(feats_primary) |
354 ((need_storage && (storage_primary | storage_secondary)) ?
355 VK_IMAGE_USAGE_STORAGE_BIT : 0);
357 }
else if (basics_secondary &&
358 (!need_storage || (need_storage && storage_secondary))) {
368 *supported_usage = map_feats_to_usage(feats_secondary);
384 static const char *lib_names[] = {
387 #elif defined(__APPLE__)
398 p->
libvulkan = dlopen(lib_names[
i], RTLD_NOW | RTLD_LOCAL);
441 { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_MEMORY },
442 { VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_SEM },
456 static VkBool32 VKAPI_CALL
vk_dbg_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
457 VkDebugUtilsMessageTypeFlagsEXT messageType,
458 const VkDebugUtilsMessengerCallbackDataEXT *
data,
465 switch (
data->messageIdNumber) {
476 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: l =
AV_LOG_VERBOSE;
break;
477 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: l =
AV_LOG_INFO;
break;
478 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: l =
AV_LOG_WARNING;
break;
479 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: l =
AV_LOG_ERROR;
break;
484 for (
int i = 0;
i <
data->cmdBufLabelCount;
i++)
490 #define ADD_VAL_TO_LIST(list, count, val) \
492 list = av_realloc_array(list, sizeof(*list), ++count); \
494 err = AVERROR(ENOMEM); \
497 list[count - 1] = av_strdup(val); \
498 if (!list[count - 1]) { \
499 err = AVERROR(ENOMEM); \
504 #define RELEASE_PROPS(props, count) \
506 for (int i = 0; i < count; i++) \
507 av_free((void *)((props)[i])); \
508 av_free((void *)props); \
522 const char *
const **
dst, uint32_t *num,
526 const char **extension_names =
NULL;
530 int err = 0, found, extensions_found = 0;
533 int optional_exts_num;
534 uint32_t sup_ext_count;
535 char *user_exts_str =
NULL;
537 VkExtensionProperties *sup_ext;
547 if (!user_exts_str) {
552 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count,
NULL);
553 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
556 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count, sup_ext);
564 if (!user_exts_str) {
569 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
570 &sup_ext_count,
NULL);
571 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
574 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
575 &sup_ext_count, sup_ext);
578 for (
int i = 0;
i < optional_exts_num;
i++) {
579 tstr = optional_exts[
i].
name;
582 if (dev && debug_mode &&
583 !strcmp(tstr, VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME)) {
587 for (
int j = 0; j < sup_ext_count; j++) {
588 if (!strcmp(tstr, sup_ext[j].extensionName)) {
605 tstr = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
607 for (
int j = 0; j < sup_ext_count; j++) {
608 if (!strcmp(tstr, sup_ext[j].extensionName)) {
626 char *save, *token =
av_strtok(user_exts_str,
"+", &save);
629 for (
int j = 0; j < sup_ext_count; j++) {
630 if (!strcmp(token, sup_ext[j].extensionName)) {
646 *
dst = extension_names;
647 *num = extensions_found;
661 const char *
const **
dst, uint32_t *num,
668 static const char layer_standard_validation[] = {
"VK_LAYER_KHRONOS_validation" };
669 int layer_standard_validation_found = 0;
671 uint32_t sup_layer_count;
672 VkLayerProperties *sup_layers;
675 char *user_layers_str =
NULL;
678 const char **enabled_layers =
NULL;
679 uint32_t enabled_layers_count = 0;
687 vk->EnumerateInstanceLayerProperties(&sup_layer_count,
NULL);
688 sup_layers =
av_malloc_array(sup_layer_count,
sizeof(VkLayerProperties));
691 vk->EnumerateInstanceLayerProperties(&sup_layer_count, sup_layers);
694 for (
int i = 0;
i < sup_layer_count;
i++)
698 if (!debug_opt && !user_layers)
703 if (!strcmp(debug_opt->
value,
"printf")) {
705 }
else if (!strcmp(debug_opt->
value,
"validate")) {
707 }
else if (!strcmp(debug_opt->
value,
"practices")) {
710 char *end_ptr =
NULL;
711 int idx = strtol(debug_opt->
value, &end_ptr, 10);
712 if (end_ptr == debug_opt->
value || end_ptr[0] !=
'\0' ||
727 for (
int i = 0;
i < sup_layer_count;
i++) {
728 if (!strcmp(layer_standard_validation, sup_layers[
i].layerName)) {
730 layer_standard_validation);
731 ADD_VAL_TO_LIST(enabled_layers, enabled_layers_count, layer_standard_validation);
733 layer_standard_validation_found = 1;
737 if (!layer_standard_validation_found) {
739 "Validation Layer \"%s\" not supported\n", layer_standard_validation);
750 if (!user_layers_str) {
755 token =
av_strtok(user_layers_str,
"+", &save);
760 if (!strcmp(layer_standard_validation, token) && layer_standard_validation_found) {
766 for (
int j = 0; j < sup_layer_count; j++) {
767 if (!strcmp(token, sup_layers[j].layerName)) {
778 if (!strcmp(layer_standard_validation, token))
782 "Layer \"%s\" not supported\n", token);
799 *
dst = enabled_layers;
800 *num = enabled_layers_count;
815 VkApplicationInfo application_info = {
816 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
817 .pApplicationName =
"ffmpeg",
821 .pEngineName =
"libavutil",
822 .apiVersion = VK_API_VERSION_1_3,
827 VkValidationFeaturesEXT validation_features = {
828 .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
830 VkInstanceCreateInfo inst_props = {
831 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
832 .pApplicationInfo = &application_info,
848 &inst_props.enabledLayerCount, debug_mode);
854 &inst_props.enabledExtensionCount, *debug_mode);
862 static const VkValidationFeatureEnableEXT feat_list_validate[] = {
863 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
864 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
865 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
867 validation_features.pEnabledValidationFeatures = feat_list_validate;
868 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_validate);
869 inst_props.pNext = &validation_features;
871 static const VkValidationFeatureEnableEXT feat_list_debug[] = {
872 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
873 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
874 VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT,
876 validation_features.pEnabledValidationFeatures = feat_list_debug;
877 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_debug);
878 inst_props.pNext = &validation_features;
880 static const VkValidationFeatureEnableEXT feat_list_practices[] = {
881 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
882 VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT,
884 validation_features.pEnabledValidationFeatures = feat_list_practices;
885 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_practices);
886 inst_props.pNext = &validation_features;
890 for (
int i = 0;
i < inst_props.enabledExtensionCount;
i++) {
891 if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
892 inst_props.ppEnabledExtensionNames[
i])) {
893 inst_props.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
900 ret = vk->CreateInstance(&inst_props, hwctx->
alloc, &hwctx->
inst);
903 if (
ret != VK_SUCCESS) {
920 VkDebugUtilsMessengerCreateInfoEXT dbg = {
921 .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
922 .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
923 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
924 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
925 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
926 .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
927 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
928 VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
933 vk->CreateDebugUtilsMessengerEXT(hwctx->
inst, &dbg,
940 RELEASE_PROPS(inst_props.ppEnabledLayerNames, inst_props.enabledLayerCount);
959 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
return "integrated";
960 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
return "discrete";
961 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
return "virtual";
962 case VK_PHYSICAL_DEVICE_TYPE_CPU:
return "software";
963 default:
return "unknown";
970 int err = 0, choice = -1;
976 VkPhysicalDevice *devices =
NULL;
977 VkPhysicalDeviceIDProperties *idp =
NULL;
978 VkPhysicalDeviceProperties2 *prop =
NULL;
979 VkPhysicalDeviceDrmPropertiesEXT *drm_prop =
NULL;
981 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num,
NULL);
982 if (
ret != VK_SUCCESS || !num) {
991 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num, devices);
992 if (
ret != VK_SUCCESS) {
1012 drm_prop =
av_calloc(num,
sizeof(*drm_prop));
1020 for (
int i = 0;
i < num;
i++) {
1022 drm_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT;
1023 idp[
i].pNext = &drm_prop[
i];
1025 idp[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
1026 prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1027 prop[
i].pNext = &idp[
i];
1029 vk->GetPhysicalDeviceProperties2(devices[
i], &prop[
i]);
1031 prop[
i].properties.deviceName,
1033 prop[
i].properties.deviceID);
1037 for (
int i = 0;
i < num;
i++) {
1038 if (!strncmp(idp[
i].deviceUUID, select->
uuid, VK_UUID_SIZE)) {
1047 for (
int i = 0;
i < num;
i++) {
1048 if ((select->
drm_major == drm_prop[
i].primaryMajor &&
1049 select->
drm_minor == drm_prop[
i].primaryMinor) ||
1050 (select->
drm_major == drm_prop[
i].renderMajor &&
1051 select->
drm_minor == drm_prop[
i].renderMinor)) {
1060 }
else if (select->
name) {
1062 for (
int i = 0;
i < num;
i++) {
1063 if (strstr(prop[
i].properties.deviceName, select->
name)) {
1074 for (
int i = 0;
i < num;
i++) {
1075 if (select->
pci_device == prop[
i].properties.deviceID) {
1086 for (
int i = 0;
i < num;
i++) {
1087 if (select->
vendor_id == prop[
i].properties.vendorID) {
1097 if (select->
index < num) {
1098 choice = select->
index;
1110 choice, prop[choice].properties.deviceName,
1112 prop[choice].properties.deviceID);
1126 VkQueueFlagBits
flags)
1129 uint32_t min_score = UINT32_MAX;
1131 for (
int i = 0;
i < num_qf;
i++) {
1132 VkQueueFlagBits qflags = qf[
i].queueFamilyProperties.queueFlags;
1135 if ((
flags & VK_QUEUE_TRANSFER_BIT) &&
1136 (qflags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)))
1137 qflags |= VK_QUEUE_TRANSFER_BIT;
1139 if (qflags &
flags) {
1140 uint32_t score =
av_popcount(qflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1141 if (score < min_score) {
1149 qf[
index].queueFamilyProperties.timestampValidBits++;
1155 VkQueueFamilyVideoPropertiesKHR *qf_vid, uint32_t num_qf,
1156 VkVideoCodecOperationFlagBitsKHR
flags)
1159 uint32_t min_score = UINT32_MAX;
1161 for (
int i = 0;
i < num_qf;
i++) {
1162 const VkQueueFlagBits qflags = qf[
i].queueFamilyProperties.queueFlags;
1163 const VkQueueFlagBits vflags = qf_vid[
i].videoCodecOperations;
1165 if (!(qflags & (VK_QUEUE_VIDEO_ENCODE_BIT_KHR | VK_QUEUE_VIDEO_DECODE_BIT_KHR)))
1168 if (vflags &
flags) {
1169 uint32_t score =
av_popcount(vflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1170 if (score < min_score) {
1178 qf[
index].queueFamilyProperties.timestampValidBits++;
1190 VkQueueFamilyProperties2 *qf =
NULL;
1191 VkQueueFamilyVideoPropertiesKHR *qf_vid =
NULL;
1194 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &num,
NULL);
1205 qf_vid =
av_malloc_array(num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
1209 for (uint32_t
i = 0;
i < num;
i++) {
1210 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1211 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1213 qf[
i] = (VkQueueFamilyProperties2) {
1214 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
1215 .pNext = &qf_vid[
i],
1220 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &num, qf);
1223 for (
int i = 0;
i < num;
i++) {
1225 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_GRAPHICS_BIT) ?
" graphics" :
"",
1226 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_COMPUTE_BIT) ?
" compute" :
"",
1227 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_TRANSFER_BIT) ?
" transfer" :
"",
1228 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ?
" encode" :
"",
1229 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_DECODE_BIT_KHR) ?
" decode" :
"",
1230 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_SPARSE_BINDING_BIT) ?
" sparse" :
"",
1231 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_OPTICAL_FLOW_BIT_NV) ?
" optical_flow" :
"",
1232 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_PROTECTED_BIT) ?
" protected" :
"",
1233 qf[
i].queueFamilyProperties.queueCount);
1237 qf[
i].queueFamilyProperties.timestampValidBits = 0;
1243 #define PICK_QF(type, vid_op) \
1249 idx = pick_video_queue_family(qf, qf_vid, num, vid_op); \
1251 idx = pick_queue_family(qf, num, type); \
1256 for (i = 0; i < hwctx->nb_qf; i++) { \
1257 if (hwctx->qf[i].idx == idx) { \
1258 hwctx->qf[i].flags |= type; \
1259 hwctx->qf[i].video_caps |= vid_op; \
1263 if (i == hwctx->nb_qf) { \
1264 hwctx->qf[i].idx = idx; \
1265 hwctx->qf[i].num = qf[idx].queueFamilyProperties.queueCount; \
1266 hwctx->qf[i].flags = type; \
1267 hwctx->qf[i].video_caps = vid_op; \
1272 PICK_QF(VK_QUEUE_GRAPHICS_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1273 PICK_QF(VK_QUEUE_COMPUTE_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1274 PICK_QF(VK_QUEUE_TRANSFER_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1275 PICK_QF(VK_QUEUE_OPTICAL_FLOW_BIT_NV, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1277 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR);
1278 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR);
1280 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR);
1281 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR);
1283 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR);
1291 sizeof(VkDeviceQueueCreateInfo));
1292 if (!cd->pQueueCreateInfos)
1295 for (uint32_t
i = 0;
i < hwctx->
nb_qf;
i++) {
1298 VkDeviceQueueCreateInfo *pc;
1299 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++) {
1300 if (hwctx->
qf[
i].
idx == cd->pQueueCreateInfos[j].queueFamilyIndex) {
1310 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++)
1311 av_free((
void *)cd->pQueueCreateInfos[
i].pQueuePriorities);
1312 av_free((
void *)cd->pQueueCreateInfos);
1316 for (uint32_t j = 0; j < hwctx->
qf[
i].
num; j++)
1319 pc = (VkDeviceQueueCreateInfo *)cd->pQueueCreateInfos;
1320 pc[cd->queueCreateInfoCount++] = (VkDeviceQueueCreateInfo) {
1321 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1322 .queueFamilyIndex = hwctx->
qf[
i].
idx,
1323 .queueCount = hwctx->
qf[
i].
num,
1328 #if FF_API_VULKAN_FIXED_QUEUES
1337 #define SET_OLD_QF(field, nb_field, type) \
1339 if (field < 0 && hwctx->qf[i].flags & type) { \
1340 field = hwctx->qf[i].idx; \
1341 nb_field = hwctx->qf[i].num; \
1345 for (uint32_t
i = 0;
i < hwctx->
nb_qf;
i++) {
1375 vk->DestroyDebugUtilsMessengerEXT(hwctx->
inst, p->
debug_ctx,
1379 vk->DestroyInstance(hwctx->
inst, hwctx->
alloc);
1403 int disable_multiplane,
1419 VkPhysicalDeviceTimelineSemaphoreFeatures timeline_features = {
1420 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES,
1422 VkPhysicalDeviceVideoMaintenance1FeaturesKHR video_maint_1_features = {
1423 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR,
1424 .pNext = &timeline_features,
1426 VkPhysicalDeviceShaderObjectFeaturesEXT shader_object_features = {
1427 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT,
1428 .pNext = &video_maint_1_features,
1430 VkPhysicalDeviceOpticalFlowFeaturesNV optical_flow_features = {
1431 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV,
1432 .pNext = &shader_object_features,
1434 VkPhysicalDeviceCooperativeMatrixFeaturesKHR coop_matrix_features = {
1435 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR,
1436 .pNext = &optical_flow_features,
1438 VkPhysicalDeviceShaderAtomicFloatFeaturesEXT atomic_float_features = {
1439 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT,
1440 .pNext = &coop_matrix_features,
1442 VkPhysicalDeviceDescriptorBufferFeaturesEXT desc_buf_features = {
1443 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT,
1444 .pNext = &atomic_float_features,
1446 VkPhysicalDeviceVulkan13Features dev_features_1_3 = {
1447 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
1448 .pNext = &desc_buf_features,
1450 VkPhysicalDeviceVulkan12Features dev_features_1_2 = {
1451 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
1452 .pNext = &dev_features_1_3,
1454 VkPhysicalDeviceVulkan11Features dev_features_1_1 = {
1455 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES,
1456 .pNext = &dev_features_1_2,
1458 VkPhysicalDeviceFeatures2 dev_features = {
1459 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
1460 .pNext = &dev_features_1_1,
1463 VkDeviceCreateInfo dev_info = {
1464 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1477 vk->GetPhysicalDeviceFeatures2(hwctx->
phys_dev, &dev_features);
1480 #define COPY_FEATURE(DST, NAME) (DST).features.NAME = dev_features.features.NAME;
1492 if (!timeline_features.timelineSemaphore) {
1500 p->
device_features_1_1.storageBuffer16BitAccess = dev_features_1_1.storageBuffer16BitAccess;
1501 p->
device_features_1_1.uniformAndStorageBuffer16BitAccess = dev_features_1_1.uniformAndStorageBuffer16BitAccess;
1508 p->
device_features_1_2.storageBuffer8BitAccess = dev_features_1_2.storageBuffer8BitAccess;
1509 p->
device_features_1_2.uniformAndStorageBuffer8BitAccess = dev_features_1_2.uniformAndStorageBuffer8BitAccess;
1511 p->
device_features_1_2.shaderSharedInt64Atomics = dev_features_1_2.shaderSharedInt64Atomics;
1513 p->
device_features_1_2.vulkanMemoryModelDeviceScope = dev_features_1_2.vulkanMemoryModelDeviceScope;
1520 p->
device_features_1_3.shaderZeroInitializeWorkgroupMemory = dev_features_1_3.shaderZeroInitializeWorkgroupMemory;
1526 p->
desc_buf_features.descriptorBufferPushDescriptors = desc_buf_features.descriptorBufferPushDescriptors;
1528 p->
atomic_float_features.shaderBufferFloat32Atomics = atomic_float_features.shaderBufferFloat32Atomics;
1529 p->
atomic_float_features.shaderBufferFloat32AtomicAdd = atomic_float_features.shaderBufferFloat32AtomicAdd;
1539 &dev_info.enabledExtensionCount, debug_mode))) {
1540 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1541 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1542 av_free((
void *)dev_info.pQueueCreateInfos);
1547 hwctx->
device_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1556 #define OPT_CHAIN(EXT_FLAG, STRUCT_P, TYPE) \
1558 if (p->vkctx.extensions & EXT_FLAG) { \
1559 (STRUCT_P)->sType = TYPE; \
1560 ff_vk_link_struct(hwctx->device_features.pNext, STRUCT_P); \
1565 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT);
1567 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT);
1569 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR);
1571 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);
1573 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV);
1575 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR);
1588 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1589 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1590 av_free((
void *)dev_info.pQueueCreateInfos);
1592 if (
ret != VK_SUCCESS) {
1595 for (
int i = 0;
i < dev_info.enabledExtensionCount;
i++)
1596 av_free((
void *)dev_info.ppEnabledExtensionNames[
i]);
1597 av_free((
void *)dev_info.ppEnabledExtensionNames);
1643 VkQueueFamilyProperties2 *qf;
1644 VkQueueFamilyVideoPropertiesKHR *qf_vid;
1645 int graph_index, comp_index, tx_index, enc_index, dec_index;
1664 p->
props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1666 p->
hprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;
1668 vk->GetPhysicalDeviceProperties2(hwctx->
phys_dev, &p->
props);
1670 p->
props.properties.deviceName);
1673 p->
props.properties.limits.optimalBufferCopyRowPitchAlignment);
1675 p->
props.properties.limits.minMemoryMapAlignment);
1677 p->
props.properties.limits.nonCoherentAtomSize);
1680 p->
hprops.minImportedHostPointerAlignment);
1684 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &qf_num,
NULL);
1694 qf_vid =
av_malloc_array(qf_num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
1700 for (uint32_t
i = 0;
i < qf_num;
i++) {
1701 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1702 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1704 qf[
i] = (VkQueueFamilyProperties2) {
1705 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
1706 .pNext = &qf_vid[
i],
1710 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &qf_num, qf);
1719 for (uint32_t
i = 0;
i < qf_num;
i++) {
1726 for (uint32_t j = 0; j < qf[
i].queueFamilyProperties.queueCount; j++) {
1737 #if FF_API_VULKAN_FIXED_QUEUES
1745 #define CHECK_QUEUE(type, required, fidx, ctx_qf, qc) \
1747 if (ctx_qf < 0 && required) { \
1748 av_log(ctx, AV_LOG_ERROR, "%s queue family is required, but marked as missing" \
1749 " in the context!\n", type); \
1750 err = AVERROR(EINVAL); \
1752 } else if (fidx < 0 || ctx_qf < 0) { \
1754 } else if (ctx_qf >= qf_num) { \
1755 av_log(ctx, AV_LOG_ERROR, "Invalid %s family index %i (device has %i families)!\n", \
1756 type, ctx_qf, qf_num); \
1757 err = AVERROR(EINVAL); \
1761 av_log(ctx, AV_LOG_VERBOSE, "Using queue family %i (queues: %i)" \
1762 " for%s%s%s%s%s\n", \
1764 ctx_qf == graph_index ? " graphics" : "", \
1765 ctx_qf == comp_index ? " compute" : "", \
1766 ctx_qf == tx_index ? " transfers" : "", \
1767 ctx_qf == enc_index ? " encode" : "", \
1768 ctx_qf == dec_index ? " decode" : ""); \
1769 graph_index = (ctx_qf == graph_index) ? -1 : graph_index; \
1770 comp_index = (ctx_qf == comp_index) ? -1 : comp_index; \
1771 tx_index = (ctx_qf == tx_index) ? -1 : tx_index; \
1772 enc_index = (ctx_qf == enc_index) ? -1 : enc_index; \
1773 dec_index = (ctx_qf == dec_index) ? -1 : dec_index; \
1786 if (!hwctx->
nb_qf) {
1787 #define ADD_QUEUE(ctx_qf, qc, flag) \
1789 if (ctx_qf != -1) { \
1790 hwctx->qf[hwctx->nb_qf++] = (AVVulkanDeviceQueueFamily) { \
1808 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
1810 hwctx->
qf[
i].
flags & (VK_QUEUE_VIDEO_DECODE_BIT_KHR |
1811 VK_QUEUE_VIDEO_ENCODE_BIT_KHR)) {
1818 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
1822 for (
int j = (
i - 1); j >= 0; j--) {
1838 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->
mprops);
1857 if (device && device[0]) {
1859 dev_select.
index = strtol(device, &end, 10);
1860 if (end == device) {
1861 dev_select.
index = 0;
1862 dev_select.
name = device;
1878 switch(src_ctx->
type) {
1882 VADisplay dpy = src_hwctx->
display;
1883 #if VA_CHECK_VERSION(1, 15, 0)
1885 VADisplayAttribute attr = {
1886 .type = VADisplayPCIID,
1891 #if VA_CHECK_VERSION(1, 15, 0)
1892 vas = vaGetDisplayAttributes(dpy, &attr, 1);
1893 if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED)
1894 dev_select.pci_device = (attr.value & 0xFFFF);
1897 if (!dev_select.pci_device) {
1898 vendor = vaQueryVendorString(dpy);
1904 if (strstr(vendor,
"AMD"))
1905 dev_select.vendor_id = 0x1002;
1914 struct stat drm_node_info;
1915 drmDevice *drm_dev_info;
1918 err = fstat(src_hwctx->
fd, &drm_node_info);
1925 dev_select.drm_major = major(drm_node_info.st_dev);
1926 dev_select.drm_minor = minor(drm_node_info.st_dev);
1927 dev_select.has_drm = 1;
1929 err = drmGetDevice(src_hwctx->
fd, &drm_dev_info);
1936 if (drm_dev_info->bustype == DRM_BUS_PCI)
1937 dev_select.pci_device = drm_dev_info->deviceinfo.pci->device_id;
1939 drmFreeDevice(&drm_dev_info);
1949 CudaFunctions *cu = cu_internal->
cuda_dl;
1951 int ret =
CHECK_CU(cu->cuDeviceGetUuid((CUuuid *)&dev_select.uuid,
1958 dev_select.has_uuid = 1;
1973 const void *hwconfig,
1982 VK_IMAGE_TILING_OPTIMAL,
1995 VK_IMAGE_TILING_OPTIMAL,
2005 constraints->
max_width = p->
props.properties.limits.maxImageDimension2D;
2006 constraints->
max_height = p->
props.properties.limits.maxImageDimension2D;
2019 VkMemoryPropertyFlagBits req_flags,
const void *alloc_extension,
2020 VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
2027 VkMemoryAllocateInfo alloc_info = {
2028 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2029 .pNext = alloc_extension,
2030 .allocationSize = req->size,
2035 for (
int i = 0;
i < p->
mprops.memoryTypeCount;
i++) {
2036 const VkMemoryType *
type = &p->
mprops.memoryTypes[
i];
2039 if (!(req->memoryTypeBits & (1 <<
i)))
2043 if ((
type->propertyFlags & req_flags) != req_flags)
2047 if (req->size > p->
mprops.memoryHeaps[
type->heapIndex].size)
2061 alloc_info.memoryTypeIndex =
index;
2063 ret = vk->AllocateMemory(dev_hwctx->
act_dev, &alloc_info,
2064 dev_hwctx->
alloc, mem);
2065 if (
ret != VK_SUCCESS) {
2071 *mem_flags |= p->
mprops.memoryTypes[
index].propertyFlags;
2081 if (internal->cuda_fc_ref) {
2087 CudaFunctions *cu = cu_internal->
cuda_dl;
2090 if (internal->cu_sem[
i])
2091 CHECK_CU(cu->cuDestroyExternalSemaphore(internal->cu_sem[
i]));
2092 if (internal->cu_mma[
i])
2093 CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[
i]));
2094 if (internal->ext_mem[
i])
2095 CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[
i]));
2097 if (internal->ext_sem_handle[
i])
2098 CloseHandle(internal->ext_sem_handle[
i]);
2099 if (internal->ext_mem_handle[
i])
2100 CloseHandle(internal->ext_mem_handle[
i]);
2125 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
2127 .pSemaphores =
f->sem,
2128 .pValues =
f->sem_value,
2129 .semaphoreCount = nb_sems,
2137 for (
int i = 0;
i < nb_images;
i++) {
2152 void *alloc_pnext,
size_t alloc_pnext_stride)
2154 int img_cnt = 0, err;
2162 while (
f->img[img_cnt]) {
2164 VkImageMemoryRequirementsInfo2 req_desc = {
2165 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
2166 .image =
f->img[img_cnt],
2168 VkMemoryDedicatedAllocateInfo ded_alloc = {
2169 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
2170 .pNext = (
void *)(((uint8_t *)alloc_pnext) + img_cnt*alloc_pnext_stride),
2172 VkMemoryDedicatedRequirements ded_req = {
2173 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
2175 VkMemoryRequirements2 req = {
2176 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
2180 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req);
2182 if (
f->tiling == VK_IMAGE_TILING_LINEAR)
2183 req.memoryRequirements.size =
FFALIGN(req.memoryRequirements.size,
2184 p->
props.properties.limits.minMemoryMapAlignment);
2187 use_ded_mem = ded_req.prefersDedicatedAllocation |
2188 ded_req.requiresDedicatedAllocation;
2190 ded_alloc.image =
f->img[img_cnt];
2194 f->tiling == VK_IMAGE_TILING_LINEAR ?
2195 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
2196 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2197 use_ded_mem ? &ded_alloc : (
void *)ded_alloc.pNext,
2198 &
f->flags, &
f->mem[img_cnt])))
2201 f->size[img_cnt] = req.memoryRequirements.size;
2202 bind_info[img_cnt].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
2203 bind_info[img_cnt].image =
f->img[img_cnt];
2204 bind_info[img_cnt].memory =
f->mem[img_cnt];
2210 ret = vk->BindImageMemory2(hwctx->
act_dev, img_cnt, bind_info);
2211 if (
ret != VK_SUCCESS) {
2239 uint32_t dst_qf = VK_QUEUE_FAMILY_IGNORED;
2240 VkImageLayout new_layout;
2241 VkAccessFlags2 new_access;
2242 VkPipelineStageFlagBits2 src_stage = VK_PIPELINE_STAGE_2_NONE;
2248 .
data = (uint8_t *)hwfc,
2252 .hw_frames_ctx = &tmp_ref,
2255 VkCommandBuffer cmd_buf;
2257 cmd_buf = exec->
buf;
2261 VK_PIPELINE_STAGE_2_NONE,
2262 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
2268 new_layout = VK_IMAGE_LAYOUT_GENERAL;
2269 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2272 new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
2273 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2276 new_layout = VK_IMAGE_LAYOUT_GENERAL;
2277 new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2280 new_layout = VK_IMAGE_LAYOUT_GENERAL;
2281 new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2282 dst_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR;
2283 src_stage = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
2286 new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR;
2287 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2290 new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR;
2291 new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2294 new_layout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR;
2295 new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2301 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
2302 new_access, new_layout, dst_qf);
2304 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
2305 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
2306 .pImageMemoryBarriers = img_bar,
2307 .imageMemoryBarrierCount = nb_img_bar,
2321 int frame_w,
int frame_h,
int plane)
2338 VkImageTiling tiling, VkImageUsageFlagBits
usage,
2339 VkImageCreateFlags
flags,
int nb_layers,
2350 VkExportSemaphoreCreateInfo ext_sem_info = {
2351 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
2353 .handleTypes = IsWindows8OrGreater()
2354 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2355 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
2357 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
2361 VkSemaphoreTypeCreateInfo sem_type_info = {
2362 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2368 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2372 VkSemaphoreCreateInfo sem_spawn = {
2373 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2374 .pNext = &sem_type_info,
2386 for (
int i = 0; (hwfc_vk->
format[
i] != VK_FORMAT_UNDEFINED);
i++) {
2387 VkImageCreateInfo create_info = {
2388 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2389 .pNext = create_pnext,
2390 .imageType = VK_IMAGE_TYPE_2D,
2394 .arrayLayers = nb_layers,
2397 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2399 .samples = VK_SAMPLE_COUNT_1_BIT,
2400 .pQueueFamilyIndices = p->
img_qfs,
2402 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2403 VK_SHARING_MODE_EXCLUSIVE,
2406 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
2409 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
2411 if (
ret != VK_SUCCESS) {
2419 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
2421 if (
ret != VK_SUCCESS) {
2429 f->layout[
i] = create_info.initialLayout;
2431 f->sem_value[
i] = 0;
2447 VkExternalMemoryHandleTypeFlags *comp_handle_types,
2448 VkExternalMemoryHandleTypeFlagBits *iexp,
2449 VkExternalMemoryHandleTypeFlagBits
exp)
2457 const VkImageDrmFormatModifierListCreateInfoEXT *drm_mod_info =
2459 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
2460 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && drm_mod_info;
2463 VkExternalImageFormatProperties eprops = {
2464 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
2466 VkImageFormatProperties2 props = {
2467 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
2470 VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
2471 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
2473 .pQueueFamilyIndices = p->
img_qfs,
2475 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2476 VK_SHARING_MODE_EXCLUSIVE,
2478 VkPhysicalDeviceExternalImageFormatInfo enext = {
2479 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
2481 .pNext = has_mods ? &phy_dev_mod_info :
NULL,
2483 VkPhysicalDeviceImageFormatInfo2 pinfo = {
2484 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
2485 .pNext = !
exp ?
NULL : &enext,
2487 .type = VK_IMAGE_TYPE_2D,
2489 .usage = hwctx->
usage,
2490 .flags = VK_IMAGE_CREATE_ALIAS_BIT,
2493 nb_mods = has_mods ? drm_mod_info->drmFormatModifierCount : 1;
2494 for (
int i = 0;
i < nb_mods;
i++) {
2496 phy_dev_mod_info.drmFormatModifier = drm_mod_info->pDrmFormatModifiers[
i];
2498 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
2501 if (
ret == VK_SUCCESS) {
2503 *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes;
2517 VkExternalMemoryHandleTypeFlags e = 0x0;
2520 VkExternalMemoryImageCreateInfo eiinfo = {
2521 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
2528 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
2529 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
2533 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
2537 eminfo[
i].sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
2539 eminfo[
i].handleTypes = e;
2552 if ( (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2553 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR))
2555 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)
2557 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR)
2559 else if (hwctx->
usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)
2613 VkImageUsageFlagBits supported_usage;
2624 (hwctx->
tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
2625 hwctx->
tiling = VK_IMAGE_TILING_LINEAR;
2635 if (hwctx->
format[0] != VK_FORMAT_UNDEFINED) {
2640 "for the current sw_format %s!\n",
2652 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
2661 NULL, &supported_usage,
2664 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
2670 if (!hwctx->
usage) {
2671 hwctx->
usage = supported_usage & (VK_BUFFER_USAGE_TRANSFER_DST_BIT |
2672 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
2673 VK_IMAGE_USAGE_STORAGE_BIT |
2674 VK_IMAGE_USAGE_SAMPLED_BIT);
2677 if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
2680 hwctx->
usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
2687 int is_lone_dpb = ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR) ||
2688 ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2689 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)));
2690 int sampleable = hwctx->
usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
2691 VK_IMAGE_USAGE_STORAGE_BIT);
2692 if (sampleable && !is_lone_dpb) {
2693 hwctx->
img_flags = VK_IMAGE_CREATE_ALIAS_BIT;
2695 hwctx->
img_flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
2696 VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
2704 if ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
2707 const VkVideoProfileListInfoKHR *pl;
2710 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
2713 for (
i = 0;
i < pl->profileCount;
i++) {
2715 if (pl->pProfiles[
i].videoCodecOperation & 0xFFFF0000)
2718 if (
i == pl->profileCount)
2719 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
2810 static const struct {
2811 uint32_t drm_fourcc;
2813 } vulkan_drm_format_map[] = {
2814 { DRM_FORMAT_R8, VK_FORMAT_R8_UNORM },
2815 { DRM_FORMAT_R16, VK_FORMAT_R16_UNORM },
2816 { DRM_FORMAT_GR88, VK_FORMAT_R8G8_UNORM },
2817 { DRM_FORMAT_RG88, VK_FORMAT_R8G8_UNORM },
2818 { DRM_FORMAT_GR1616, VK_FORMAT_R16G16_UNORM },
2819 { DRM_FORMAT_RG1616, VK_FORMAT_R16G16_UNORM },
2820 { DRM_FORMAT_ARGB8888, VK_FORMAT_B8G8R8A8_UNORM },
2821 { DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM },
2822 { DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM },
2823 { DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM },
2824 { DRM_FORMAT_ARGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
2825 { DRM_FORMAT_ABGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
2826 { DRM_FORMAT_XRGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
2827 { DRM_FORMAT_XBGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
2830 #ifdef DRM_FORMAT_XYUV8888
2831 { DRM_FORMAT_XYUV8888, VK_FORMAT_R8G8B8A8_UNORM },
2832 { DRM_FORMAT_XVYU12_16161616, VK_FORMAT_R16G16B16A16_UNORM} ,
2835 { DRM_FORMAT_Y416, VK_FORMAT_R16G16B16A16_UNORM },
2839 static inline VkFormat drm_to_vulkan_fmt(uint32_t drm_fourcc)
2842 if (vulkan_drm_format_map[
i].drm_fourcc == drm_fourcc)
2843 return vulkan_drm_format_map[
i].vk_format;
2844 return VK_FORMAT_UNDEFINED;
2853 int bind_counts = 0;
2863 if (drm_to_vulkan_fmt(
desc->layers[
i].format) == VK_FORMAT_UNDEFINED) {
2865 desc->layers[
i].format);
2876 f->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
2878 for (
int i = 0;
i <
desc->nb_layers;
i++) {
2882 VkSemaphoreTypeCreateInfo sem_type_info = {
2883 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2884 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2887 VkSemaphoreCreateInfo sem_spawn = {
2888 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2889 .pNext = &sem_type_info,
2894 VkImageDrmFormatModifierExplicitCreateInfoEXT ext_img_mod_spec = {
2895 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
2896 .drmFormatModifier =
desc->objects[0].format_modifier,
2897 .drmFormatModifierPlaneCount =
planes,
2898 .pPlaneLayouts = (
const VkSubresourceLayout *)&ext_img_layouts,
2900 VkExternalMemoryImageCreateInfo ext_img_spec = {
2901 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
2902 .pNext = &ext_img_mod_spec,
2903 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
2905 VkImageCreateInfo create_info = {
2906 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2907 .pNext = &ext_img_spec,
2908 .imageType = VK_IMAGE_TYPE_2D,
2909 .format = drm_to_vulkan_fmt(
desc->layers[
i].format),
2914 .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
2915 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2917 .samples = VK_SAMPLE_COUNT_1_BIT,
2918 .pQueueFamilyIndices = p->
img_qfs,
2920 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2921 VK_SHARING_MODE_EXCLUSIVE,
2925 VkExternalImageFormatProperties ext_props = {
2926 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
2928 VkImageFormatProperties2 props_ret = {
2929 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
2930 .pNext = &ext_props,
2932 VkPhysicalDeviceImageDrmFormatModifierInfoEXT props_drm_mod = {
2933 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
2934 .drmFormatModifier = ext_img_mod_spec.drmFormatModifier,
2935 .pQueueFamilyIndices = create_info.pQueueFamilyIndices,
2936 .queueFamilyIndexCount = create_info.queueFamilyIndexCount,
2937 .sharingMode = create_info.sharingMode,
2939 VkPhysicalDeviceExternalImageFormatInfo props_ext = {
2940 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
2941 .pNext = &props_drm_mod,
2942 .handleType = ext_img_spec.handleTypes,
2944 VkPhysicalDeviceImageFormatInfo2 fmt_props;
2947 create_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT |
2948 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2950 create_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT |
2951 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2953 fmt_props = (VkPhysicalDeviceImageFormatInfo2) {
2954 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
2955 .pNext = &props_ext,
2956 .format = create_info.format,
2957 .type = create_info.imageType,
2958 .tiling = create_info.tiling,
2959 .usage = create_info.usage,
2960 .flags = create_info.flags,
2964 ret = vk->GetPhysicalDeviceImageFormatProperties2(hwctx->
phys_dev,
2965 &fmt_props, &props_ret);
2966 if (
ret != VK_SUCCESS) {
2974 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
2978 for (
int j = 0; j <
planes; j++) {
2979 ext_img_layouts[j].offset =
desc->layers[
i].planes[j].offset;
2980 ext_img_layouts[j].rowPitch =
desc->layers[
i].planes[j].pitch;
2981 ext_img_layouts[j].size = 0;
2982 ext_img_layouts[j].arrayPitch = 0;
2983 ext_img_layouts[j].depthPitch = 0;
2987 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
2989 if (
ret != VK_SUCCESS) {
2996 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
2998 if (
ret != VK_SUCCESS) {
3005 f->queue_family[
i] = VK_QUEUE_FAMILY_EXTERNAL;
3006 f->layout[
i] = create_info.initialLayout;
3008 f->sem_value[
i] = 0;
3011 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3013 VkImageMemoryRequirementsInfo2 req_desc = {
3014 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
3017 VkMemoryDedicatedRequirements ded_req = {
3018 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
3020 VkMemoryRequirements2 req2 = {
3021 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3026 VkMemoryFdPropertiesKHR fdmp = {
3027 .sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR,
3033 VkImportMemoryFdInfoKHR idesc = {
3034 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
3035 .fd = dup(
desc->objects[
desc->layers[
i].planes[0].object_index].fd),
3036 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3038 VkMemoryDedicatedAllocateInfo ded_alloc = {
3039 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
3041 .image = req_desc.image,
3045 ret = vk->GetMemoryFdPropertiesKHR(hwctx->
act_dev,
3046 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3048 if (
ret != VK_SUCCESS) {
3056 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req2);
3059 req2.memoryRequirements.memoryTypeBits = fdmp.memoryTypeBits;
3062 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
3063 (ded_req.prefersDedicatedAllocation ||
3064 ded_req.requiresDedicatedAllocation) ?
3065 &ded_alloc : ded_alloc.pNext,
3066 &
f->flags, &
f->mem[
i]);
3072 f->size[
i] = req2.memoryRequirements.size;
3075 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3077 for (
int j = 0; j <
planes; j++) {
3078 VkImageAspectFlagBits aspect = j == 0 ? VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT :
3079 j == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3080 VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
3082 plane_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO;
3084 plane_info[bind_counts].planeAspect = aspect;
3086 bind_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
3088 bind_info[bind_counts].image =
f->img[
i];
3089 bind_info[bind_counts].memory =
f->mem[
i];
3092 bind_info[bind_counts].memoryOffset = 0;
3099 ret = vk->BindImageMemory2(hwctx->
act_dev, bind_counts, bind_info);
3100 if (
ret != VK_SUCCESS) {
3130 #ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
3132 VkCommandBuffer cmd_buf;
3138 for (
int i = 0;
i <
desc->nb_objects;
i++) {
3139 VkSemaphoreTypeCreateInfo sem_type_info = {
3140 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3141 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
3143 VkSemaphoreCreateInfo sem_spawn = {
3144 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3145 .pNext = &sem_type_info,
3147 VkImportSemaphoreFdInfoKHR import_info;
3148 struct dma_buf_export_sync_file implicit_fd_info = {
3149 .flags = DMA_BUF_SYNC_READ,
3153 if (ioctl(
desc->objects[
i].fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE,
3154 &implicit_fd_info)) {
3159 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3163 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3164 hwctx->
alloc, &drm_sync_sem[
i]);
3165 if (
ret != VK_SUCCESS) {
3170 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3174 import_info = (VkImportSemaphoreFdInfoKHR) {
3175 .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
3176 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
3177 .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
3178 .semaphore = drm_sync_sem[
i],
3179 .fd = implicit_fd_info.fd,
3182 ret = vk->ImportSemaphoreFdKHR(hwctx->
act_dev, &import_info);
3183 if (
ret != VK_SUCCESS) {
3188 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3194 cmd_buf = exec->
buf;
3200 drm_sync_sem,
desc->nb_objects,
3201 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 1);
3206 VK_PIPELINE_STAGE_2_NONE,
3207 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
3212 VK_PIPELINE_STAGE_2_NONE,
3213 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
3215 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT : 0x0) |
3217 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT : 0x0),
3218 VK_IMAGE_LAYOUT_GENERAL,
3219 VK_QUEUE_FAMILY_IGNORED);
3221 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
3222 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
3223 .pImageMemoryBarriers = img_bar,
3224 .imageMemoryBarrierCount = nb_img_bar,
3235 "image may be corrupted.\n");
3250 if ((err = vulkan_map_from_drm_frame_desc(hwfc, &
f,
src,
flags)))
3254 dst->data[0] = (uint8_t *)
f;
3256 dst->height =
src->height;
3259 &vulkan_unmap_from_drm,
f);
3263 err = vulkan_map_from_drm_frame_sync(hwfc,
dst,
src,
flags);
3286 VASurfaceID surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
3292 vaSyncSurface(vaapi_ctx->display, surface_id);
3300 err = vulkan_map_from_drm(dst_fc,
dst,
tmp,
flags);
3333 CudaFunctions *cu = cu_internal->
cuda_dl;
3334 CUarray_format cufmt =
desc->comp[0].depth > 8 ? CU_AD_FORMAT_UNSIGNED_INT16 :
3335 CU_AD_FORMAT_UNSIGNED_INT8;
3340 if (!dst_int->cuda_fc_ref) {
3342 if (!dst_int->cuda_fc_ref)
3346 CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = {
3351 .NumChannels = 1 + ((
planes == 2) &&
i),
3359 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3360 .type = IsWindows8OrGreater()
3361 ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
3362 : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT,
3363 .size = dst_f->
size[
i],
3365 VkMemoryGetWin32HandleInfoKHR export_info = {
3366 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
3367 .memory = dst_f->
mem[
i],
3368 .handleType = IsWindows8OrGreater()
3369 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
3370 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
3372 VkSemaphoreGetWin32HandleInfoKHR sem_export = {
3373 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
3374 .semaphore = dst_f->
sem[
i],
3375 .handleType = IsWindows8OrGreater()
3376 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
3377 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
3379 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3383 ret = vk->GetMemoryWin32HandleKHR(hwctx->
act_dev, &export_info,
3384 &ext_desc.handle.win32.handle);
3385 if (
ret != VK_SUCCESS) {
3391 dst_int->ext_mem_handle[
i] = ext_desc.handle.win32.handle;
3393 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3394 .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
3395 .size = dst_f->
size[
i],
3397 VkMemoryGetFdInfoKHR export_info = {
3398 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
3399 .memory = dst_f->
mem[
i],
3400 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
3402 VkSemaphoreGetFdInfoKHR sem_export = {
3403 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
3404 .semaphore = dst_f->
sem[
i],
3405 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
3407 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3411 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
3412 &ext_desc.handle.fd);
3413 if (
ret != VK_SUCCESS) {
3421 ret =
CHECK_CU(cu->cuImportExternalMemory(&dst_int->ext_mem[
i], &ext_desc));
3424 close(ext_desc.handle.fd);
3431 tex_desc.arrayDesc.Width = p_w;
3432 tex_desc.arrayDesc.Height = p_h;
3434 ret =
CHECK_CU(cu->cuExternalMemoryGetMappedMipmappedArray(&dst_int->cu_mma[
i],
3435 dst_int->ext_mem[
i],
3442 ret =
CHECK_CU(cu->cuMipmappedArrayGetLevel(&dst_int->cu_array[
i],
3443 dst_int->cu_mma[
i], 0));
3450 ret = vk->GetSemaphoreWin32HandleKHR(hwctx->
act_dev, &sem_export,
3451 &ext_sem_desc.handle.win32.handle);
3453 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &sem_export,
3454 &ext_sem_desc.handle.fd);
3456 if (
ret != VK_SUCCESS) {
3463 dst_int->ext_sem_handle[
i] = ext_sem_desc.handle.win32.handle;
3466 ret =
CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[
i],
3470 close(ext_sem_desc.handle.fd);
3500 CudaFunctions *cu = cu_internal->
cuda_dl;
3510 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
3514 err = vulkan_export_to_cuda(hwfc,
src->hw_frames_ctx,
dst);
3523 s_w_par[
i].params.fence.value = dst_f->
sem_value[
i] + 0;
3524 s_s_par[
i].params.fence.value = dst_f->
sem_value[
i] + 1;
3527 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
3528 planes, cuda_dev->stream));
3533 CUDA_MEMCPY2D cpy = {
3534 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
3535 .srcDevice = (CUdeviceptr)
src->data[
i],
3536 .srcPitch =
src->linesize[
i],
3539 .dstMemoryType = CU_MEMORYTYPE_ARRAY,
3540 .dstArray = dst_int->cu_array[
i],
3546 cpy.WidthInBytes = p_w *
desc->comp[
i].step;
3549 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
3554 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
3555 planes, cuda_dev->stream));
3581 switch (
src->format) {
3586 return vulkan_map_from_vaapi(hwfc,
dst,
src,
flags);
3592 return vulkan_map_from_drm(hwfc,
dst,
src,
flags);
3602 typedef struct VulkanDRMMapping {
3617 static inline uint32_t vulkan_fmt_to_drm(
VkFormat vkfmt)
3620 if (vulkan_drm_format_map[
i].vk_format == vkfmt)
3621 return vulkan_drm_format_map[
i].drm_fourcc;
3622 return DRM_FORMAT_INVALID;
3637 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
3638 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
3640 VkSemaphoreWaitInfo wait_info = {
3641 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
3643 .semaphoreCount =
planes,
3655 wait_info.pSemaphores =
f->sem;
3656 wait_info.pValues =
f->sem_value;
3658 vk->WaitSemaphores(hwctx->
act_dev, &wait_info, UINT64_MAX);
3664 ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->
act_dev,
f->img[0],
3666 if (
ret != VK_SUCCESS) {
3672 for (
int i = 0; (
i <
planes) && (
f->mem[
i]);
i++) {
3673 VkMemoryGetFdInfoKHR export_info = {
3674 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
3675 .memory =
f->mem[
i],
3676 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3679 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
3681 if (
ret != VK_SUCCESS) {
3694 VkSubresourceLayout
layout;
3695 VkImageSubresource sub = {
3696 .aspectMask = VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT,
3700 drm_desc->
layers[
i].
format = vulkan_fmt_to_drm(plane_vkfmt);
3711 if (
f->tiling == VK_IMAGE_TILING_OPTIMAL)
3714 vk->GetImageSubresourceLayout(hwctx->
act_dev,
f->img[
i], &sub, &
layout);
3723 dst->height =
src->height;
3724 dst->data[0] = (uint8_t *)drm_desc;
3768 switch (
dst->format) {
3778 return vulkan_map_to_vaapi(hwfc,
dst,
src,
flags);
3790 AVFrame *swf, VkBufferImageCopy *region,
3800 const VkMappedMemoryRange flush_info = {
3801 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
3802 .memory = vkbuf->
mem,
3803 .size = VK_WHOLE_SIZE,
3806 if (!(vkbuf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) && !upload) {
3807 ret = vk->InvalidateMappedMemoryRanges(hwctx->
act_dev, 1,
3809 if (
ret != VK_SUCCESS) {
3818 region[
i].bufferRowLength,
3822 region[
i].imageExtent.height);
3824 if (!(vkbuf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) && upload) {
3825 ret = vk->FlushMappedMemoryRanges(hwctx->
act_dev, 1,
3827 if (
ret != VK_SUCCESS) {
3838 AVFrame *swf, VkBufferImageCopy *region,
int upload)
3845 size_t buf_offset = 0;
3854 p->
props.properties.limits.optimalBufferCopyRowPitchAlignment);
3855 size = p_h*linesize;
3857 region[
i] = (VkBufferImageCopy) {
3858 .bufferOffset = buf_offset,
3859 .bufferRowLength = linesize,
3860 .bufferImageHeight = p_h,
3861 .imageSubresource.layerCount = 1,
3862 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
3867 p->
props.properties.limits.optimalBufferCopyOffsetAlignment);
3871 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
3872 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
3874 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
3875 VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
3885 VkExternalMemoryBufferCreateInfo *create_desc,
3886 VkImportMemoryHostPointerInfoEXT *import_desc,
3887 VkMemoryHostPointerPropertiesEXT props)
3895 VkBufferCreateInfo buf_spawn = {
3896 .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
3897 .pNext = create_desc,
3899 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
3902 VkMemoryRequirements req = {
3904 .alignment = p->
hprops.minImportedHostPointerAlignment,
3905 .memoryTypeBits = props.memoryTypeBits,
3909 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
3910 import_desc, &vkb->
flags, &vkb->
mem);
3915 if (
ret != VK_SUCCESS) {
3921 if (
ret != VK_SUCCESS) {
3939 AVFrame *swf, VkBufferImageCopy *region,
int upload)
3949 VkExternalMemoryBufferCreateInfo create_desc = {
3950 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
3951 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
3953 VkImportMemoryHostPointerInfoEXT import_desc = {
3954 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
3955 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
3957 VkMemoryHostPointerPropertiesEXT props;
3974 offs = (uintptr_t)swf->
data[
i] % p->
hprops.minImportedHostPointerAlignment;
3975 import_desc.pHostPointer = swf->
data[
i] - offs;
3977 props = (VkMemoryHostPointerPropertiesEXT) {
3978 VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT,
3980 ret = vk->GetMemoryHostPointerPropertiesEXT(hwctx->
act_dev,
3981 import_desc.handleType,
3982 import_desc.pHostPointer,
3984 if (!(
ret == VK_SUCCESS && props.memoryTypeBits)) {
3990 region[
i] = (VkBufferImageCopy) {
3991 .bufferOffset = offs,
3993 .bufferImageHeight = p_h,
3994 .imageSubresource.layerCount = 1,
3995 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4000 buffer_size = offs + swf->
linesize[
i]*p_h;
4001 buffer_size =
FFALIGN(buffer_size, p->
props.properties.limits.minMemoryMapAlignment);
4002 buffer_size =
FFALIGN(buffer_size, p->
hprops.minImportedHostPointerAlignment);
4012 upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4013 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
4014 buffer_size, &create_desc, &import_desc,
4024 if (!
dst[*nb_bufs]) {
4036 for (
int i = 0;
i < (*nb_bufs);
i++)
4050 int host_mapped = 0;
4058 static const VkImageAspectFlags plane_aspect[] = { VK_IMAGE_ASPECT_COLOR_BIT,
4059 VK_IMAGE_ASPECT_PLANE_0_BIT,
4060 VK_IMAGE_ASPECT_PLANE_1_BIT,
4061 VK_IMAGE_ASPECT_PLANE_2_BIT, };
4069 VkCommandBuffer cmd_buf;
4102 cmd_buf = exec->
buf;
4108 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
4109 VK_PIPELINE_STAGE_2_TRANSFER_BIT);
4123 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
4124 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,
4125 upload ? VK_ACCESS_TRANSFER_WRITE_BIT :
4126 VK_ACCESS_TRANSFER_READ_BIT,
4127 upload ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL :
4128 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4129 VK_QUEUE_FAMILY_IGNORED);
4131 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
4132 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
4133 .pImageMemoryBarriers = img_bar,
4134 .imageMemoryBarrierCount = nb_img_bar,
4138 int buf_idx =
FFMIN(
i, (nb_bufs - 1));
4139 int img_idx =
FFMIN(
i, (nb_images - 1));
4142 uint32_t orig_stride = region[
i].bufferRowLength;
4143 region[
i].bufferRowLength /=
desc->comp[
i].step;
4144 region[
i].imageSubresource.aspectMask = plane_aspect[(
planes != nb_images) +
4148 vk->CmdCopyBufferToImage(cmd_buf, vkbuf->
buf,
4149 hwf_vk->
img[img_idx],
4150 img_bar[img_idx].newLayout,
4153 vk->CmdCopyImageToBuffer(cmd_buf, hwf_vk->
img[img_idx],
4154 img_bar[img_idx].newLayout,
4158 region[
i].bufferRowLength = orig_stride;
4164 }
else if (!upload) {
4171 for (
int i = 0;
i < nb_bufs;
i++)
4182 switch (
src->format) {
4186 if ((p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY) &&
4187 (p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM))
4192 return vulkan_transfer_data_from_cuda(hwfc,
dst,
src);
4195 if (
src->hw_frames_ctx)
4218 CudaFunctions *cu = cu_internal->
cuda_dl;
4228 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
4232 err = vulkan_export_to_cuda(hwfc,
dst->hw_frames_ctx,
src);
4241 s_w_par[
i].params.fence.value = dst_f->
sem_value[
i] + 0;
4242 s_s_par[
i].params.fence.value = dst_f->
sem_value[
i] + 1;
4245 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
4246 planes, cuda_dev->stream));
4251 CUDA_MEMCPY2D cpy = {
4252 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
4253 .dstDevice = (CUdeviceptr)
dst->data[
i],
4254 .dstPitch =
dst->linesize[
i],
4257 .srcMemoryType = CU_MEMORYTYPE_ARRAY,
4258 .srcArray = dst_int->cu_array[
i],
4264 cpy.WidthInBytes =
w *
desc->comp[
i].step;
4267 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
4272 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
4273 planes, cuda_dev->stream));
4299 switch (
dst->format) {
4303 if ((p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY) &&
4304 (p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM))
4309 return vulkan_transfer_data_to_cuda(hwfc,
dst,
src);
4312 if (
dst->hw_frames_ctx)