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>
67 #define CHECK_CU(x) FF_CUDA_CHECK_DL(cuda_cu, cu, x)
97 VkPhysicalDeviceProperties2
props;
98 VkPhysicalDeviceMemoryProperties
mprops;
99 VkPhysicalDeviceExternalMemoryHostPropertiesEXT
hprops;
166 #define ASPECT_2PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT)
167 #define ASPECT_3PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)
179 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_GRAY8, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8_UNORM } },
180 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
181 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GRAYF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_SFLOAT } },
184 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_XV36, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
185 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_BGRA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
186 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGBA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
187 { VK_FORMAT_R8G8B8_UNORM,
AV_PIX_FMT_RGB24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8_UNORM } },
188 { VK_FORMAT_B8G8R8_UNORM,
AV_PIX_FMT_BGR24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8_UNORM } },
189 { VK_FORMAT_R16G16B16_UNORM,
AV_PIX_FMT_RGB48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16_UNORM } },
190 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_RGBA64, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
191 { VK_FORMAT_R5G6B5_UNORM_PACK16,
AV_PIX_FMT_RGB565, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R5G6B5_UNORM_PACK16 } },
192 { VK_FORMAT_B5G6R5_UNORM_PACK16,
AV_PIX_FMT_BGR565, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B5G6R5_UNORM_PACK16 } },
193 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_BGR0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
194 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGB0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
195 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_X2RGB10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
198 { 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 } },
199 { 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 } },
200 { 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 } },
201 { 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 } },
205 { 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 } },
206 { 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 } },
211 { 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 } },
212 { 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 } },
217 { 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 } },
218 { 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 } },
236 { VK_FORMAT_G8B8G8R8_422_UNORM,
AV_PIX_FMT_YUYV422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
237 { VK_FORMAT_B8G8R8G8_422_UNORM,
AV_PIX_FMT_UYVY422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
238 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
AV_PIX_FMT_Y210, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
239 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
AV_PIX_FMT_Y212, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
260 #define FN_MAP_TO(dst_t, dst_name, src_t, src_name) \
261 static av_unused dst_t map_ ##src_name## _to_ ##dst_name(src_t src) \
264 MAP_TO(VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT, \
265 VK_IMAGE_USAGE_SAMPLED_BIT); \
266 MAP_TO(VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT, \
267 VK_IMAGE_USAGE_TRANSFER_SRC_BIT); \
268 MAP_TO(VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT, \
269 VK_IMAGE_USAGE_TRANSFER_DST_BIT); \
270 MAP_TO(VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT, \
271 VK_IMAGE_USAGE_STORAGE_BIT); \
272 MAP_TO(VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT, \
273 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); \
274 MAP_TO(VK_FORMAT_FEATURE_2_VIDEO_DECODE_OUTPUT_BIT_KHR, \
275 VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR); \
276 MAP_TO(VK_FORMAT_FEATURE_2_VIDEO_DECODE_DPB_BIT_KHR, \
277 VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR); \
278 MAP_TO(VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR, \
279 VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR); \
280 MAP_TO(VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR, \
281 VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR); \
285 #define MAP_TO(flag1, flag2) if (src & flag2) dst |= flag1;
286 FN_MAP_TO(VkFormatFeatureFlagBits2, feats, VkImageUsageFlags,
usage)
288 #define MAP_TO(flag1, flag2) if (src & flag1) dst |= flag2;
289 FN_MAP_TO(VkImageUsageFlags,
usage, VkFormatFeatureFlagBits2, feats)
294 VkImageTiling tiling,
297 VkImageAspectFlags *
aspect,
298 VkImageUsageFlags *supported_usage,
299 int disable_multiplane,
int need_storage)
305 const VkFormatFeatureFlagBits2 basic_flags = VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
306 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
307 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
311 VkFormatProperties3 fprops = {
312 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3,
314 VkFormatProperties2 prop = {
315 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
318 VkFormatFeatureFlagBits2 feats_primary, feats_secondary;
319 int basics_primary = 0, basics_secondary = 0;
320 int storage_primary = 0, storage_secondary = 0;
322 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
326 feats_primary = tiling == VK_IMAGE_TILING_LINEAR ?
327 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
328 basics_primary = (feats_primary & basic_flags) == basic_flags;
329 storage_primary = !!(feats_primary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
332 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
335 feats_secondary = tiling == VK_IMAGE_TILING_LINEAR ?
336 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
337 basics_secondary = (feats_secondary & basic_flags) == basic_flags;
338 storage_secondary = !!(feats_secondary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
340 basics_secondary = basics_primary;
341 storage_secondary = storage_primary;
344 if (basics_primary &&
346 (!need_storage || (need_storage && (storage_primary | storage_secondary)))) {
354 *supported_usage = map_feats_to_usage(feats_primary) |
355 ((need_storage && (storage_primary | storage_secondary)) ?
356 VK_IMAGE_USAGE_STORAGE_BIT : 0);
358 }
else if (basics_secondary &&
359 (!need_storage || (need_storage && storage_secondary))) {
369 *supported_usage = map_feats_to_usage(feats_secondary);
385 static const char *lib_names[] = {
388 #elif defined(__APPLE__)
399 p->
libvulkan = dlopen(lib_names[
i], RTLD_NOW | RTLD_LOCAL);
440 { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_MEMORY },
441 { VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_SEM },
452 static VkBool32 VKAPI_CALL
vk_dbg_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
453 VkDebugUtilsMessageTypeFlagsEXT messageType,
454 const VkDebugUtilsMessengerCallbackDataEXT *
data,
461 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: l =
AV_LOG_VERBOSE;
break;
462 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: l =
AV_LOG_INFO;
break;
463 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: l =
AV_LOG_WARNING;
break;
464 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: l =
AV_LOG_ERROR;
break;
469 for (
int i = 0;
i <
data->cmdBufLabelCount;
i++)
475 #define ADD_VAL_TO_LIST(list, count, val) \
477 list = av_realloc_array(list, sizeof(*list), ++count); \
479 err = AVERROR(ENOMEM); \
482 list[count - 1] = av_strdup(val); \
483 if (!list[count - 1]) { \
484 err = AVERROR(ENOMEM); \
489 #define RELEASE_PROPS(props, count) \
491 for (int i = 0; i < count; i++) \
492 av_free((void *)((props)[i])); \
493 av_free((void *)props); \
497 const char *
const **dst, uint32_t *num,
int debug)
500 const char **extension_names =
NULL;
504 int err = 0, found, extensions_found = 0;
507 int optional_exts_num;
508 uint32_t sup_ext_count;
509 char *user_exts_str =
NULL;
511 VkExtensionProperties *sup_ext;
521 if (!user_exts_str) {
526 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count,
NULL);
527 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
530 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count, sup_ext);
538 if (!user_exts_str) {
543 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
544 &sup_ext_count,
NULL);
545 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
548 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
549 &sup_ext_count, sup_ext);
552 for (
int i = 0;
i < optional_exts_num;
i++) {
553 tstr = optional_exts[
i].
name;
555 for (
int j = 0; j < sup_ext_count; j++) {
556 if (!strcmp(tstr, sup_ext[j].extensionName)) {
570 tstr = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
572 for (
int j = 0; j < sup_ext_count; j++) {
573 if (!strcmp(tstr, sup_ext[j].extensionName)) {
591 char *save, *token =
av_strtok(user_exts_str,
"+", &save);
594 for (
int j = 0; j < sup_ext_count; j++) {
595 if (!strcmp(token, sup_ext[j].extensionName)) {
611 *dst = extension_names;
612 *num = extensions_found;
626 const char *
const **dst, uint32_t *num,
629 static const char default_layer[] = {
"VK_LAYER_KHRONOS_validation" };
631 int found = 0, err = 0;
635 uint32_t sup_layer_count;
636 VkLayerProperties *sup_layers;
639 char *user_layers_str =
NULL;
642 const char **enabled_layers =
NULL;
643 uint32_t enabled_layers_count = 0;
646 int debug = debug_opt && strtol(debug_opt->
value,
NULL, 10);
649 if (debug_opt && !debug)
652 vk->EnumerateInstanceLayerProperties(&sup_layer_count,
NULL);
653 sup_layers =
av_malloc_array(sup_layer_count,
sizeof(VkLayerProperties));
656 vk->EnumerateInstanceLayerProperties(&sup_layer_count, sup_layers);
659 for (
int i = 0;
i < sup_layer_count;
i++)
665 for (
int i = 0;
i < sup_layer_count;
i++) {
666 if (!strcmp(default_layer, sup_layers[
i].layerName)) {
681 if (!user_layers_str) {
686 token =
av_strtok(user_layers_str,
"+", &save);
689 if (!strcmp(default_layer, token)) {
699 for (
int j = 0; j < sup_layer_count; j++) {
700 if (!strcmp(token, sup_layers[j].layerName)) {
710 "Validation Layer \"%s\" not support.\n", token);
722 *dst = enabled_layers;
723 *num = enabled_layers_count;
737 int err = 0, debug_mode = 0;
742 VkApplicationInfo application_info = {
743 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
744 .pApplicationName =
"ffmpeg",
748 .pEngineName =
"libavutil",
749 .apiVersion = VK_API_VERSION_1_3,
754 VkValidationFeaturesEXT validation_features = {
755 .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
757 VkInstanceCreateInfo inst_props = {
758 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
759 .pApplicationInfo = &application_info,
775 &inst_props.enabledLayerCount, &debug_mode);
781 &inst_props.enabledExtensionCount, debug_mode);
788 VkValidationFeatureEnableEXT feat_list[] = {
789 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
790 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
791 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
793 validation_features.pEnabledValidationFeatures = feat_list;
794 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list);
795 inst_props.pNext = &validation_features;
799 for (
int i = 0;
i < inst_props.enabledExtensionCount;
i++) {
800 if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
801 inst_props.ppEnabledExtensionNames[
i])) {
802 inst_props.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
809 ret = vk->CreateInstance(&inst_props, hwctx->
alloc, &hwctx->
inst);
812 if (
ret != VK_SUCCESS) {
826 VkDebugUtilsMessengerCreateInfoEXT dbg = {
827 .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
828 .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
829 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
830 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
831 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
832 .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
833 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
834 VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
839 vk->CreateDebugUtilsMessengerEXT(hwctx->
inst, &dbg,
846 RELEASE_PROPS(inst_props.ppEnabledLayerNames, inst_props.enabledLayerCount);
865 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
return "integrated";
866 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
return "discrete";
867 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
return "virtual";
868 case VK_PHYSICAL_DEVICE_TYPE_CPU:
return "software";
869 default:
return "unknown";
876 int err = 0, choice = -1;
882 VkPhysicalDevice *devices =
NULL;
883 VkPhysicalDeviceIDProperties *idp =
NULL;
884 VkPhysicalDeviceProperties2 *prop =
NULL;
885 VkPhysicalDeviceDrmPropertiesEXT *drm_prop =
NULL;
887 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num,
NULL);
888 if (
ret != VK_SUCCESS || !num) {
897 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num, devices);
898 if (
ret != VK_SUCCESS) {
918 drm_prop =
av_calloc(num,
sizeof(*drm_prop));
926 for (
int i = 0;
i < num;
i++) {
928 drm_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT;
929 idp[
i].pNext = &drm_prop[
i];
931 idp[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
932 prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
933 prop[
i].pNext = &idp[
i];
935 vk->GetPhysicalDeviceProperties2(devices[
i], &prop[
i]);
937 prop[
i].properties.deviceName,
939 prop[
i].properties.deviceID);
943 for (
int i = 0;
i < num;
i++) {
944 if (!strncmp(idp[
i].deviceUUID, select->
uuid, VK_UUID_SIZE)) {
953 for (
int i = 0;
i < num;
i++) {
954 if ((select->
drm_major == drm_prop[
i].primaryMajor &&
955 select->
drm_minor == drm_prop[
i].primaryMinor) ||
956 (select->
drm_major == drm_prop[
i].renderMajor &&
957 select->
drm_minor == drm_prop[
i].renderMinor)) {
966 }
else if (select->
name) {
968 for (
int i = 0;
i < num;
i++) {
969 if (strstr(prop[
i].properties.deviceName, select->
name)) {
980 for (
int i = 0;
i < num;
i++) {
981 if (select->
pci_device == prop[
i].properties.deviceID) {
992 for (
int i = 0;
i < num;
i++) {
993 if (select->
vendor_id == prop[
i].properties.vendorID) {
1003 if (select->
index < num) {
1004 choice = select->
index;
1016 choice, prop[choice].properties.deviceName,
1018 prop[choice].properties.deviceID);
1032 VkQueueFlagBits
flags)
1035 uint32_t min_score = UINT32_MAX;
1037 for (
int i = 0;
i < num_qf;
i++) {
1038 const VkQueueFlagBits qflags = qf[
i].queueFlags;
1039 if (qflags &
flags) {
1040 uint32_t score =
av_popcount(qflags) + qf[
i].timestampValidBits;
1041 if (score < min_score) {
1049 qf[
index].timestampValidBits++;
1058 VkQueueFamilyProperties *qf =
NULL;
1062 int graph_index, comp_index, tx_index, enc_index, dec_index;
1065 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &num,
NULL);
1077 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &num, qf);
1080 for (
int i = 0;
i < num;
i++) {
1082 ((qf[
i].queueFlags) & VK_QUEUE_GRAPHICS_BIT) ?
" graphics" :
"",
1083 ((qf[
i].queueFlags) & VK_QUEUE_COMPUTE_BIT) ?
" compute" :
"",
1084 ((qf[
i].queueFlags) & VK_QUEUE_TRANSFER_BIT) ?
" transfer" :
"",
1085 ((qf[
i].queueFlags) & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ?
" encode" :
"",
1086 ((qf[
i].queueFlags) & VK_QUEUE_VIDEO_DECODE_BIT_KHR) ?
" decode" :
"",
1087 ((qf[
i].queueFlags) & VK_QUEUE_SPARSE_BINDING_BIT) ?
" sparse" :
"",
1088 ((qf[
i].queueFlags) & VK_QUEUE_PROTECTED_BIT) ?
" protected" :
"",
1093 qf[
i].timestampValidBits = 0;
1116 #define SETUP_QUEUE(qf_idx) \
1117 if (qf_idx > -1) { \
1118 int fidx = qf_idx; \
1119 int qc = qf[fidx].queueCount; \
1120 VkDeviceQueueCreateInfo *pc; \
1122 if (fidx == graph_index) { \
1123 hwctx->queue_family_index = fidx; \
1124 hwctx->nb_graphics_queues = qc; \
1127 if (fidx == comp_index) { \
1128 hwctx->queue_family_comp_index = fidx; \
1129 hwctx->nb_comp_queues = qc; \
1132 if (fidx == tx_index) { \
1133 hwctx->queue_family_tx_index = fidx; \
1134 hwctx->nb_tx_queues = qc; \
1137 if (fidx == enc_index) { \
1138 hwctx->queue_family_encode_index = fidx; \
1139 hwctx->nb_encode_queues = qc; \
1142 if (fidx == dec_index) { \
1143 hwctx->queue_family_decode_index = fidx; \
1144 hwctx->nb_decode_queues = qc; \
1148 pc = av_realloc((void *)cd->pQueueCreateInfos, \
1149 sizeof(*pc) * (cd->queueCreateInfoCount + 1)); \
1152 return AVERROR(ENOMEM); \
1154 cd->pQueueCreateInfos = pc; \
1155 pc = &pc[cd->queueCreateInfoCount]; \
1157 weights = av_malloc(qc * sizeof(float)); \
1160 return AVERROR(ENOMEM); \
1163 memset(pc, 0, sizeof(*pc)); \
1164 pc->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; \
1165 pc->queueFamilyIndex = fidx; \
1166 pc->queueCount = qc; \
1167 pc->pQueuePriorities = weights; \
1169 for (int i = 0; i < qc; i++) \
1170 weights[i] = 1.0f / qc; \
1172 cd->queueCreateInfoCount++; \
1203 vk->DestroyDebugUtilsMessengerEXT(hwctx->
inst, p->
debug_ctx,
1207 vk->DestroyInstance(hwctx->
inst, hwctx->
alloc);
1231 int disable_multiplane,
1246 VkPhysicalDeviceTimelineSemaphoreFeatures timeline_features = {
1247 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES,
1249 VkPhysicalDeviceCooperativeMatrixFeaturesKHR coop_matrix_features = {
1250 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR,
1251 .pNext = &timeline_features,
1253 VkPhysicalDeviceShaderAtomicFloatFeaturesEXT atomic_float_features = {
1254 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT,
1255 .pNext = &coop_matrix_features,
1257 VkPhysicalDeviceDescriptorBufferFeaturesEXT desc_buf_features = {
1258 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT,
1259 .pNext = &atomic_float_features,
1261 VkPhysicalDeviceVulkan13Features dev_features_1_3 = {
1262 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
1263 .pNext = &desc_buf_features,
1265 VkPhysicalDeviceVulkan12Features dev_features_1_2 = {
1266 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
1267 .pNext = &dev_features_1_3,
1269 VkPhysicalDeviceVulkan11Features dev_features_1_1 = {
1270 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES,
1271 .pNext = &dev_features_1_2,
1273 VkPhysicalDeviceFeatures2 dev_features = {
1274 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
1275 .pNext = &dev_features_1_1,
1278 VkDeviceCreateInfo dev_info = {
1279 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1282 hwctx->
device_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1290 p->
desc_buf_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT;
1292 p->
atomic_float_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT;
1294 p->
coop_matrix_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR;
1307 vk->GetPhysicalDeviceFeatures2(hwctx->
phys_dev, &dev_features);
1310 #define COPY_FEATURE(DST, NAME) (DST).features.NAME = dev_features.features.NAME;
1322 if (!timeline_features.timelineSemaphore) {
1336 p->
device_features_1_2.storageBuffer8BitAccess = dev_features_1_2.storageBuffer8BitAccess;
1337 p->
device_features_1_2.uniformAndStorageBuffer8BitAccess = dev_features_1_2.uniformAndStorageBuffer8BitAccess;
1339 p->
device_features_1_2.shaderSharedInt64Atomics = dev_features_1_2.shaderSharedInt64Atomics;
1341 p->
device_features_1_2.vulkanMemoryModelDeviceScope = dev_features_1_2.vulkanMemoryModelDeviceScope;
1348 p->
device_features_1_3.shaderZeroInitializeWorkgroupMemory = dev_features_1_3.shaderZeroInitializeWorkgroupMemory;
1352 p->
desc_buf_features.descriptorBufferPushDescriptors = desc_buf_features.descriptorBufferPushDescriptors;
1354 p->
atomic_float_features.shaderBufferFloat32Atomics = atomic_float_features.shaderBufferFloat32Atomics;
1355 p->
atomic_float_features.shaderBufferFloat32AtomicAdd = atomic_float_features.shaderBufferFloat32AtomicAdd;
1366 &dev_info.enabledExtensionCount, 0))) {
1367 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1368 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1369 av_free((
void *)dev_info.pQueueCreateInfos);
1376 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1377 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1378 av_free((
void *)dev_info.pQueueCreateInfos);
1380 if (
ret != VK_SUCCESS) {
1383 for (
int i = 0;
i < dev_info.enabledExtensionCount;
i++)
1384 av_free((
void *)dev_info.ppEnabledExtensionNames[
i]);
1385 av_free((
void *)dev_info.ppEnabledExtensionNames);
1431 VkQueueFamilyProperties *qf;
1432 int graph_index, comp_index, tx_index, enc_index, dec_index;
1451 p->
props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1453 p->
hprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;
1455 vk->GetPhysicalDeviceProperties2(hwctx->
phys_dev, &p->
props);
1457 p->
props.properties.deviceName);
1460 p->
props.properties.limits.optimalBufferCopyRowPitchAlignment);
1462 p->
props.properties.limits.minMemoryMapAlignment);
1464 p->
props.properties.limits.nonCoherentAtomSize);
1467 p->
hprops.minImportedHostPointerAlignment);
1471 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &qf_num,
NULL);
1481 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &qf_num, qf);
1490 for (uint32_t
i = 0;
i < qf_num;
i++) {
1496 for (uint32_t j = 0; j < qf[
i].queueCount; j++) {
1515 #define CHECK_QUEUE(type, required, fidx, ctx_qf, qc) \
1517 if (ctx_qf < 0 && required) { \
1518 av_log(ctx, AV_LOG_ERROR, "%s queue family is required, but marked as missing" \
1519 " in the context!\n", type); \
1520 return AVERROR(EINVAL); \
1521 } else if (fidx < 0 || ctx_qf < 0) { \
1523 } else if (ctx_qf >= qf_num) { \
1524 av_log(ctx, AV_LOG_ERROR, "Invalid %s family index %i (device has %i families)!\n", \
1525 type, ctx_qf, qf_num); \
1526 return AVERROR(EINVAL); \
1529 av_log(ctx, AV_LOG_VERBOSE, "Using queue family %i (queues: %i)" \
1530 " for%s%s%s%s%s\n", \
1532 ctx_qf == graph_index ? " graphics" : "", \
1533 ctx_qf == comp_index ? " compute" : "", \
1534 ctx_qf == tx_index ? " transfers" : "", \
1535 ctx_qf == enc_index ? " encode" : "", \
1536 ctx_qf == dec_index ? " decode" : ""); \
1537 graph_index = (ctx_qf == graph_index) ? -1 : graph_index; \
1538 comp_index = (ctx_qf == comp_index) ? -1 : comp_index; \
1539 tx_index = (ctx_qf == tx_index) ? -1 : tx_index; \
1540 enc_index = (ctx_qf == enc_index) ? -1 : enc_index; \
1541 dec_index = (ctx_qf == dec_index) ? -1 : dec_index; \
1542 p->img_qfs[p->nb_img_qfs++] = ctx_qf; \
1559 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->
mprops);
1575 if (device && device[0]) {
1577 dev_select.
index = strtol(device, &end, 10);
1578 if (end == device) {
1579 dev_select.
index = 0;
1580 dev_select.
name = device;
1596 switch(src_ctx->
type) {
1600 VADisplay dpy = src_hwctx->
display;
1601 #if VA_CHECK_VERSION(1, 15, 0)
1603 VADisplayAttribute attr = {
1604 .type = VADisplayPCIID,
1609 #if VA_CHECK_VERSION(1, 15, 0)
1610 vas = vaGetDisplayAttributes(dpy, &attr, 1);
1611 if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED)
1612 dev_select.pci_device = (attr.value & 0xFFFF);
1615 if (!dev_select.pci_device) {
1616 vendor = vaQueryVendorString(dpy);
1622 if (strstr(vendor,
"AMD"))
1623 dev_select.vendor_id = 0x1002;
1632 struct stat drm_node_info;
1633 drmDevice *drm_dev_info;
1636 err = fstat(src_hwctx->
fd, &drm_node_info);
1643 dev_select.drm_major = major(drm_node_info.st_dev);
1644 dev_select.drm_minor = minor(drm_node_info.st_dev);
1645 dev_select.has_drm = 1;
1647 err = drmGetDevice(src_hwctx->
fd, &drm_dev_info);
1654 if (drm_dev_info->bustype == DRM_BUS_PCI)
1655 dev_select.pci_device = drm_dev_info->deviceinfo.pci->device_id;
1657 drmFreeDevice(&drm_dev_info);
1667 CudaFunctions *cu = cu_internal->
cuda_dl;
1669 int ret =
CHECK_CU(cu->cuDeviceGetUuid((CUuuid *)&dev_select.uuid,
1676 dev_select.has_uuid = 1;
1691 const void *hwconfig,
1700 VK_IMAGE_TILING_OPTIMAL,
1713 VK_IMAGE_TILING_OPTIMAL,
1723 constraints->
max_width = p->
props.properties.limits.maxImageDimension2D;
1724 constraints->
max_height = p->
props.properties.limits.maxImageDimension2D;
1737 VkMemoryPropertyFlagBits req_flags,
const void *alloc_extension,
1738 VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
1745 VkMemoryAllocateInfo alloc_info = {
1746 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1747 .pNext = alloc_extension,
1748 .allocationSize = req->size,
1753 for (
int i = 0;
i < p->
mprops.memoryTypeCount;
i++) {
1754 const VkMemoryType *
type = &p->
mprops.memoryTypes[
i];
1757 if (!(req->memoryTypeBits & (1 <<
i)))
1761 if ((
type->propertyFlags & req_flags) != req_flags)
1765 if (req->size > p->
mprops.memoryHeaps[
type->heapIndex].size)
1779 alloc_info.memoryTypeIndex =
index;
1781 ret = vk->AllocateMemory(dev_hwctx->
act_dev, &alloc_info,
1782 dev_hwctx->
alloc, mem);
1783 if (
ret != VK_SUCCESS) {
1789 *mem_flags |= p->
mprops.memoryTypes[
index].propertyFlags;
1799 if (internal->cuda_fc_ref) {
1805 CudaFunctions *cu = cu_internal->
cuda_dl;
1808 if (internal->cu_sem[
i])
1809 CHECK_CU(cu->cuDestroyExternalSemaphore(internal->cu_sem[
i]));
1810 if (internal->cu_mma[
i])
1811 CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[
i]));
1812 if (internal->ext_mem[
i])
1813 CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[
i]));
1815 if (internal->ext_sem_handle[
i])
1816 CloseHandle(internal->ext_sem_handle[
i]);
1817 if (internal->ext_mem_handle[
i])
1818 CloseHandle(internal->ext_mem_handle[
i]);
1843 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
1845 .pSemaphores =
f->sem,
1846 .pValues =
f->sem_value,
1847 .semaphoreCount = nb_sems,
1855 for (
int i = 0;
i < nb_images;
i++) {
1870 void *alloc_pnext,
size_t alloc_pnext_stride)
1872 int img_cnt = 0, err;
1880 while (
f->img[img_cnt]) {
1882 VkImageMemoryRequirementsInfo2 req_desc = {
1883 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
1884 .image =
f->img[img_cnt],
1886 VkMemoryDedicatedAllocateInfo ded_alloc = {
1887 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1888 .pNext = (
void *)(((uint8_t *)alloc_pnext) + img_cnt*alloc_pnext_stride),
1890 VkMemoryDedicatedRequirements ded_req = {
1891 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
1893 VkMemoryRequirements2 req = {
1894 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
1898 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req);
1900 if (
f->tiling == VK_IMAGE_TILING_LINEAR)
1901 req.memoryRequirements.size =
FFALIGN(req.memoryRequirements.size,
1902 p->
props.properties.limits.minMemoryMapAlignment);
1905 use_ded_mem = ded_req.prefersDedicatedAllocation |
1906 ded_req.requiresDedicatedAllocation;
1908 ded_alloc.image =
f->img[img_cnt];
1912 f->tiling == VK_IMAGE_TILING_LINEAR ?
1913 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
1914 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
1915 use_ded_mem ? &ded_alloc : (
void *)ded_alloc.pNext,
1916 &
f->flags, &
f->mem[img_cnt])))
1919 f->size[img_cnt] = req.memoryRequirements.size;
1920 bind_info[img_cnt].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
1921 bind_info[img_cnt].image =
f->img[img_cnt];
1922 bind_info[img_cnt].memory =
f->mem[img_cnt];
1928 ret = vk->BindImageMemory2(hwctx->
act_dev, img_cnt, bind_info);
1929 if (
ret != VK_SUCCESS) {
1955 uint32_t dst_qf = VK_QUEUE_FAMILY_IGNORED;
1956 VkImageLayout new_layout;
1957 VkAccessFlags2 new_access;
1958 VkPipelineStageFlagBits2 src_stage = VK_PIPELINE_STAGE_2_NONE;
1964 .
data = (uint8_t *)hwfc,
1968 .hw_frames_ctx = &tmp_ref,
1971 VkCommandBuffer cmd_buf;
1973 cmd_buf = exec->
buf;
1977 VK_PIPELINE_STAGE_2_NONE,
1978 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
1984 new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1985 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
1988 new_layout = VK_IMAGE_LAYOUT_GENERAL;
1989 new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
1992 new_layout = VK_IMAGE_LAYOUT_GENERAL;
1993 new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
1994 dst_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR;
1995 src_stage = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
1998 new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR;
1999 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2002 new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR;
2003 new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2009 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
2010 new_access, new_layout, dst_qf);
2012 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
2013 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
2014 .pImageMemoryBarriers = img_bar,
2015 .imageMemoryBarrierCount = nb_img_bar,
2029 int frame_w,
int frame_h,
int plane)
2046 VkImageTiling tiling, VkImageUsageFlagBits
usage,
2047 VkImageCreateFlags
flags,
int nb_layers,
2058 VkExportSemaphoreCreateInfo ext_sem_info = {
2059 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
2061 .handleTypes = IsWindows8OrGreater()
2062 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2063 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
2065 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
2069 VkSemaphoreTypeCreateInfo sem_type_info = {
2070 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2076 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2080 VkSemaphoreCreateInfo sem_spawn = {
2081 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2082 .pNext = &sem_type_info,
2094 for (
int i = 0; (hwfc_vk->
format[
i] != VK_FORMAT_UNDEFINED);
i++) {
2095 VkImageCreateInfo create_info = {
2096 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2097 .pNext = create_pnext,
2098 .imageType = VK_IMAGE_TYPE_2D,
2102 .arrayLayers = nb_layers,
2105 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2107 .samples = VK_SAMPLE_COUNT_1_BIT,
2108 .pQueueFamilyIndices = p->
img_qfs,
2110 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2111 VK_SHARING_MODE_EXCLUSIVE,
2114 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
2117 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
2119 if (
ret != VK_SUCCESS) {
2127 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
2129 if (
ret != VK_SUCCESS) {
2137 f->layout[
i] = create_info.initialLayout;
2139 f->sem_value[
i] = 0;
2155 VkExternalMemoryHandleTypeFlags *comp_handle_types,
2156 VkExternalMemoryHandleTypeFlagBits *iexp,
2157 VkExternalMemoryHandleTypeFlagBits
exp)
2165 const VkImageDrmFormatModifierListCreateInfoEXT *drm_mod_info =
2167 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
2168 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && drm_mod_info;
2171 VkExternalImageFormatProperties eprops = {
2172 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
2174 VkImageFormatProperties2 props = {
2175 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
2178 VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
2179 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
2181 .pQueueFamilyIndices = p->
img_qfs,
2183 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2184 VK_SHARING_MODE_EXCLUSIVE,
2186 VkPhysicalDeviceExternalImageFormatInfo enext = {
2187 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
2189 .pNext = has_mods ? &phy_dev_mod_info :
NULL,
2191 VkPhysicalDeviceImageFormatInfo2 pinfo = {
2192 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
2193 .pNext = !
exp ?
NULL : &enext,
2195 .type = VK_IMAGE_TYPE_2D,
2197 .usage = hwctx->
usage,
2198 .flags = VK_IMAGE_CREATE_ALIAS_BIT,
2201 nb_mods = has_mods ? drm_mod_info->drmFormatModifierCount : 1;
2202 for (
int i = 0;
i < nb_mods;
i++) {
2204 phy_dev_mod_info.drmFormatModifier = drm_mod_info->pDrmFormatModifiers[
i];
2206 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
2209 if (
ret == VK_SUCCESS) {
2211 *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes;
2225 VkExternalMemoryHandleTypeFlags e = 0x0;
2228 VkExternalMemoryImageCreateInfo eiinfo = {
2229 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
2236 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
2237 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
2241 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
2245 eminfo[
i].sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
2247 eminfo[
i].handleTypes = e;
2260 if ( (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2261 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR))
2263 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)
2297 if (
fp->modifier_info) {
2298 if (
fp->modifier_info->pDrmFormatModifiers)
2299 av_freep(&
fp->modifier_info->pDrmFormatModifiers);
2315 VkImageUsageFlagBits supported_usage;
2326 (hwctx->
tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
2327 hwctx->
tiling = VK_IMAGE_TILING_LINEAR;
2337 if (hwctx->
format[0] != VK_FORMAT_UNDEFINED) {
2342 "for the current sw_format %s!\n",
2353 hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT);
2362 NULL, &supported_usage,
2364 hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT);
2370 if (!hwctx->
usage) {
2371 hwctx->
usage = supported_usage & (VK_BUFFER_USAGE_TRANSFER_DST_BIT |
2372 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
2373 VK_IMAGE_USAGE_STORAGE_BIT |
2374 VK_IMAGE_USAGE_SAMPLED_BIT);
2381 int is_lone_dpb = (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2382 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR);
2383 int sampleable = hwctx->
usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
2384 VK_IMAGE_USAGE_STORAGE_BIT);
2385 if (sampleable && !is_lone_dpb) {
2386 hwctx->
img_flags = VK_IMAGE_CREATE_ALIAS_BIT;
2388 hwctx->
img_flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
2389 VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
2480 static const struct {
2481 uint32_t drm_fourcc;
2483 } vulkan_drm_format_map[] = {
2484 { DRM_FORMAT_R8, VK_FORMAT_R8_UNORM },
2485 { DRM_FORMAT_R16, VK_FORMAT_R16_UNORM },
2486 { DRM_FORMAT_GR88, VK_FORMAT_R8G8_UNORM },
2487 { DRM_FORMAT_RG88, VK_FORMAT_R8G8_UNORM },
2488 { DRM_FORMAT_GR1616, VK_FORMAT_R16G16_UNORM },
2489 { DRM_FORMAT_RG1616, VK_FORMAT_R16G16_UNORM },
2490 { DRM_FORMAT_ARGB8888, VK_FORMAT_B8G8R8A8_UNORM },
2491 { DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM },
2492 { DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM },
2493 { DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM },
2496 #ifdef DRM_FORMAT_XYUV8888
2497 { DRM_FORMAT_XYUV8888, VK_FORMAT_R8G8B8A8_UNORM },
2498 { DRM_FORMAT_XVYU12_16161616, VK_FORMAT_R16G16B16A16_UNORM} ,
2501 { DRM_FORMAT_Y416, VK_FORMAT_R16G16B16A16_UNORM },
2505 static inline VkFormat drm_to_vulkan_fmt(uint32_t drm_fourcc)
2508 if (vulkan_drm_format_map[
i].drm_fourcc == drm_fourcc)
2509 return vulkan_drm_format_map[
i].vk_format;
2510 return VK_FORMAT_UNDEFINED;
2519 int bind_counts = 0;
2530 if (drm_to_vulkan_fmt(
desc->layers[
i].format) == VK_FORMAT_UNDEFINED) {
2532 desc->layers[
i].format);
2543 f->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
2545 for (
int i = 0;
i <
desc->nb_layers;
i++) {
2549 VkSemaphoreTypeCreateInfo sem_type_info = {
2550 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2551 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2554 VkSemaphoreCreateInfo sem_spawn = {
2555 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2556 .pNext = &sem_type_info,
2561 VkImageDrmFormatModifierExplicitCreateInfoEXT ext_img_mod_spec = {
2562 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
2563 .drmFormatModifier =
desc->objects[0].format_modifier,
2564 .drmFormatModifierPlaneCount =
planes,
2565 .pPlaneLayouts = (
const VkSubresourceLayout *)&ext_img_layouts,
2567 VkExternalMemoryImageCreateInfo ext_img_spec = {
2568 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
2569 .pNext = &ext_img_mod_spec,
2570 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
2572 VkImageCreateInfo create_info = {
2573 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2574 .pNext = &ext_img_spec,
2575 .imageType = VK_IMAGE_TYPE_2D,
2576 .format = drm_to_vulkan_fmt(
desc->layers[
i].format),
2581 .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
2582 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2583 .usage = VK_IMAGE_USAGE_SAMPLED_BIT |
2584 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
2585 .samples = VK_SAMPLE_COUNT_1_BIT,
2586 .pQueueFamilyIndices = p->
img_qfs,
2588 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2589 VK_SHARING_MODE_EXCLUSIVE,
2593 VkExternalImageFormatProperties ext_props = {
2594 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
2596 VkImageFormatProperties2 props_ret = {
2597 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
2598 .pNext = &ext_props,
2600 VkPhysicalDeviceImageDrmFormatModifierInfoEXT props_drm_mod = {
2601 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
2602 .drmFormatModifier = ext_img_mod_spec.drmFormatModifier,
2603 .pQueueFamilyIndices = create_info.pQueueFamilyIndices,
2604 .queueFamilyIndexCount = create_info.queueFamilyIndexCount,
2605 .sharingMode = create_info.sharingMode,
2607 VkPhysicalDeviceExternalImageFormatInfo props_ext = {
2608 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
2609 .pNext = &props_drm_mod,
2610 .handleType = ext_img_spec.handleTypes,
2612 VkPhysicalDeviceImageFormatInfo2 fmt_props = {
2613 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
2614 .pNext = &props_ext,
2615 .format = create_info.format,
2616 .type = create_info.imageType,
2617 .tiling = create_info.tiling,
2618 .usage = create_info.usage,
2619 .flags = create_info.flags,
2623 ret = vk->GetPhysicalDeviceImageFormatProperties2(hwctx->
phys_dev,
2624 &fmt_props, &props_ret);
2625 if (
ret != VK_SUCCESS) {
2633 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
2637 for (
int j = 0; j <
planes; j++) {
2638 ext_img_layouts[j].offset =
desc->layers[
i].planes[j].offset;
2639 ext_img_layouts[j].rowPitch =
desc->layers[
i].planes[j].pitch;
2640 ext_img_layouts[j].size = 0;
2641 ext_img_layouts[j].arrayPitch = 0;
2642 ext_img_layouts[j].depthPitch = 0;
2646 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
2648 if (
ret != VK_SUCCESS) {
2655 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
2657 if (
ret != VK_SUCCESS) {
2670 f->layout[
i] = create_info.initialLayout;
2672 f->sem_value[
i] = 0;
2675 for (
int i = 0;
i <
desc->nb_layers;
i++) {
2677 VkImageMemoryRequirementsInfo2 req_desc = {
2678 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
2681 VkMemoryDedicatedRequirements ded_req = {
2682 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
2684 VkMemoryRequirements2 req2 = {
2685 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
2690 VkMemoryFdPropertiesKHR fdmp = {
2691 .sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR,
2697 VkImportMemoryFdInfoKHR idesc = {
2698 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
2699 .fd = dup(
desc->objects[
desc->layers[
i].planes[0].object_index].fd),
2700 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
2702 VkMemoryDedicatedAllocateInfo ded_alloc = {
2703 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
2705 .image = req_desc.image,
2709 ret = vk->GetMemoryFdPropertiesKHR(hwctx->
act_dev,
2710 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
2712 if (
ret != VK_SUCCESS) {
2720 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req2);
2723 req2.memoryRequirements.memoryTypeBits = fdmp.memoryTypeBits;
2726 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2727 (ded_req.prefersDedicatedAllocation ||
2728 ded_req.requiresDedicatedAllocation) ?
2729 &ded_alloc : ded_alloc.pNext,
2730 &
f->flags, &
f->mem[
i]);
2736 f->size[
i] = req2.memoryRequirements.size;
2739 for (
int i = 0;
i <
desc->nb_layers;
i++) {
2741 for (
int j = 0; j <
planes; j++) {
2742 VkImageAspectFlagBits aspect = j == 0 ? VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT :
2743 j == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
2744 VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
2746 plane_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO;
2748 plane_info[bind_counts].planeAspect = aspect;
2750 bind_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
2752 bind_info[bind_counts].image =
f->img[
i];
2753 bind_info[bind_counts].memory =
f->mem[
i];
2756 bind_info[bind_counts].memoryOffset = 0;
2763 ret = vk->BindImageMemory2(hwctx->
act_dev, bind_counts, bind_info);
2764 if (
ret != VK_SUCCESS) {
2791 if ((err = vulkan_map_from_drm_frame_desc(hwfc, &
f,
src)))
2795 dst->
data[0] = (uint8_t *)
f;
2800 &vulkan_unmap_from_drm,
f);
2823 VASurfaceID surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
2829 vaSyncSurface(vaapi_ctx->display, surface_id);
2837 err = vulkan_map_from_drm(dst_fc, dst,
tmp,
flags);
2870 CudaFunctions *cu = cu_internal->
cuda_dl;
2871 CUarray_format cufmt =
desc->comp[0].depth > 8 ? CU_AD_FORMAT_UNSIGNED_INT16 :
2872 CU_AD_FORMAT_UNSIGNED_INT8;
2877 if (!dst_int->cuda_fc_ref) {
2879 if (!dst_int->cuda_fc_ref)
2883 CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = {
2888 .NumChannels = 1 + ((
planes == 2) &&
i),
2896 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
2897 .type = IsWindows8OrGreater()
2898 ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
2899 : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT,
2900 .size = dst_f->
size[
i],
2902 VkMemoryGetWin32HandleInfoKHR export_info = {
2903 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
2904 .memory = dst_f->
mem[
i],
2905 .handleType = IsWindows8OrGreater()
2906 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
2907 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
2909 VkSemaphoreGetWin32HandleInfoKHR sem_export = {
2910 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
2911 .semaphore = dst_f->
sem[
i],
2912 .handleType = IsWindows8OrGreater()
2913 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2914 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
2916 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
2920 ret = vk->GetMemoryWin32HandleKHR(hwctx->
act_dev, &export_info,
2921 &ext_desc.handle.win32.handle);
2922 if (
ret != VK_SUCCESS) {
2928 dst_int->ext_mem_handle[
i] = ext_desc.handle.win32.handle;
2930 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
2931 .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
2932 .size = dst_f->
size[
i],
2934 VkMemoryGetFdInfoKHR export_info = {
2935 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
2936 .memory = dst_f->
mem[
i],
2937 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
2939 VkSemaphoreGetFdInfoKHR sem_export = {
2940 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
2941 .semaphore = dst_f->
sem[
i],
2942 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
2944 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
2948 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
2949 &ext_desc.handle.fd);
2950 if (
ret != VK_SUCCESS) {
2958 ret =
CHECK_CU(cu->cuImportExternalMemory(&dst_int->ext_mem[
i], &ext_desc));
2961 close(ext_desc.handle.fd);
2968 tex_desc.arrayDesc.Width = p_w;
2969 tex_desc.arrayDesc.Height = p_h;
2971 ret =
CHECK_CU(cu->cuExternalMemoryGetMappedMipmappedArray(&dst_int->cu_mma[
i],
2972 dst_int->ext_mem[
i],
2979 ret =
CHECK_CU(cu->cuMipmappedArrayGetLevel(&dst_int->cu_array[
i],
2980 dst_int->cu_mma[
i], 0));
2987 ret = vk->GetSemaphoreWin32HandleKHR(hwctx->
act_dev, &sem_export,
2988 &ext_sem_desc.handle.win32.handle);
2990 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &sem_export,
2991 &ext_sem_desc.handle.fd);
2993 if (
ret != VK_SUCCESS) {
3000 dst_int->ext_sem_handle[
i] = ext_sem_desc.handle.win32.handle;
3003 ret =
CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[
i],
3007 close(ext_sem_desc.handle.fd);
3037 CudaFunctions *cu = cu_internal->
cuda_dl;
3047 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
3051 err = vulkan_export_to_cuda(hwfc,
src->hw_frames_ctx, dst);
3060 s_w_par[
i].params.fence.value = dst_f->
sem_value[
i] + 0;
3061 s_s_par[
i].params.fence.value = dst_f->
sem_value[
i] + 1;
3064 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
3065 planes, cuda_dev->stream));
3070 CUDA_MEMCPY2D cpy = {
3071 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
3072 .srcDevice = (CUdeviceptr)
src->data[
i],
3073 .srcPitch =
src->linesize[
i],
3076 .dstMemoryType = CU_MEMORYTYPE_ARRAY,
3077 .dstArray = dst_int->cu_array[
i],
3083 cpy.WidthInBytes = p_w *
desc->comp[
i].step;
3086 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
3091 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
3092 planes, cuda_dev->stream));
3118 switch (
src->format) {
3123 return vulkan_map_from_vaapi(hwfc, dst,
src,
flags);
3129 return vulkan_map_from_drm(hwfc, dst,
src,
flags);
3139 typedef struct VulkanDRMMapping {
3154 static inline uint32_t vulkan_fmt_to_drm(
VkFormat vkfmt)
3157 if (vulkan_drm_format_map[
i].vk_format == vkfmt)
3158 return vulkan_drm_format_map[
i].drm_fourcc;
3159 return DRM_FORMAT_INVALID;
3174 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
3175 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
3177 VkSemaphoreWaitInfo wait_info = {
3178 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
3180 .semaphoreCount =
planes,
3192 wait_info.pSemaphores =
f->sem;
3193 wait_info.pValues =
f->sem_value;
3195 vk->WaitSemaphores(hwctx->
act_dev, &wait_info, UINT64_MAX);
3201 ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->
act_dev,
f->img[0],
3203 if (
ret != VK_SUCCESS) {
3209 for (
int i = 0; (
i <
planes) && (
f->mem[
i]);
i++) {
3210 VkMemoryGetFdInfoKHR export_info = {
3211 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
3212 .memory =
f->mem[
i],
3213 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3216 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
3218 if (
ret != VK_SUCCESS) {
3231 VkSubresourceLayout
layout;
3232 VkImageSubresource sub = {
3233 .aspectMask = VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT,
3237 drm_desc->
layers[
i].
format = vulkan_fmt_to_drm(plane_vkfmt);
3248 if (
f->tiling == VK_IMAGE_TILING_OPTIMAL)
3251 vk->GetImageSubresourceLayout(hwctx->
act_dev,
f->img[
i], &sub, &
layout);
3261 dst->
data[0] = (uint8_t *)drm_desc;
3309 return vulkan_map_to_drm(hwfc, dst,
src,
flags);
3315 return vulkan_map_to_vaapi(hwfc, dst,
src,
flags);
3337 const int *buf_stride,
int w,
3352 VkCommandBuffer cmd_buf;
3355 cmd_buf = exec->
buf;
3363 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
3364 VK_PIPELINE_STAGE_2_TRANSFER_BIT);
3369 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
3370 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,
3371 to_buf ? VK_ACCESS_TRANSFER_READ_BIT :
3372 VK_ACCESS_TRANSFER_WRITE_BIT,
3373 to_buf ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL :
3374 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
3375 VK_QUEUE_FAMILY_IGNORED);
3377 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
3378 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
3379 .pImageMemoryBarriers = img_bar,
3380 .imageMemoryBarrierCount = nb_img_bar,
3384 for (
int i = 0;
i < pixfmt_planes;
i++) {
3385 int idx =
FFMIN(
i, nb_images - 1);
3386 VkImageAspectFlags plane_aspect[] = { VK_IMAGE_ASPECT_COLOR_BIT,
3387 VK_IMAGE_ASPECT_PLANE_0_BIT,
3388 VK_IMAGE_ASPECT_PLANE_1_BIT,
3389 VK_IMAGE_ASPECT_PLANE_2_BIT, };
3392 VkBufferImageCopy buf_reg = {
3393 .bufferOffset = buf_offsets[
i],
3394 .bufferRowLength = buf_stride[
i] /
desc->comp[
i].step,
3395 .imageSubresource.layerCount = 1,
3396 .imageSubresource.aspectMask = plane_aspect[(pixfmt_planes != nb_images) +
3397 i*(pixfmt_planes != nb_images)],
3398 .imageOffset = { 0, 0, 0, },
3404 buf_reg.bufferImageHeight = p_h;
3405 buf_reg.imageExtent = (VkExtent3D){ p_w, p_h, 1, };
3408 vk->CmdCopyImageToBuffer(cmd_buf,
frame->img[idx],
3409 img_bar[0].newLayout,
3413 vk->CmdCopyBufferToImage(cmd_buf, vkbuf->
buf,
frame->img[idx],
3414 img_bar[0].newLayout,
3460 VkExternalMemoryBufferCreateInfo create_desc = {
3461 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
3462 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
3465 VkImportMemoryHostPointerInfoEXT import_desc = {
3466 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
3467 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
3470 VkMemoryHostPointerPropertiesEXT p_props = {
3471 .sType = VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT,
3481 offs = (uintptr_t)swf->
data[
i] % p->
hprops.minImportedHostPointerAlignment;
3482 import_desc.pHostPointer = swf->
data[
i] - offs;
3487 p->
hprops.minImportedHostPointerAlignment);
3489 ret = vk->GetMemoryHostPointerPropertiesEXT(hwctx->
act_dev,
3490 import_desc.handleType,
3491 import_desc.pHostPointer,
3493 if (
ret == VK_SUCCESS && p_props.memoryTypeBits) {
3495 buf_offsets[
i] = offs;
3499 if (!host_mapped[
i])
3503 host_mapped[
i] ? &create_desc :
NULL,
3504 host_mapped[
i] ? &import_desc :
NULL,
3505 from ? VK_BUFFER_USAGE_TRANSFER_DST_BIT :
3506 VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
3507 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
3509 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : 0x0));
3554 (
const uint8_t *)
tmp.data[
i],
tmp.linesize[
i],
3575 switch (
src->format) {
3579 if ((p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY) &&
3580 (p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM))
3585 return vulkan_transfer_data_from_cuda(hwfc, dst,
src);
3588 if (
src->hw_frames_ctx)
3611 CudaFunctions *cu = cu_internal->
cuda_dl;
3621 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
3634 s_w_par[
i].params.fence.value = dst_f->
sem_value[
i] + 0;
3635 s_s_par[
i].params.fence.value = dst_f->
sem_value[
i] + 1;
3638 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
3639 planes, cuda_dev->stream));
3644 CUDA_MEMCPY2D cpy = {
3645 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
3646 .dstDevice = (CUdeviceptr)dst->
data[
i],
3650 .srcMemoryType = CU_MEMORYTYPE_ARRAY,
3651 .srcArray = dst_int->cu_array[
i],
3657 cpy.WidthInBytes =
w *
desc->comp[
i].step;
3660 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
3665 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
3666 planes, cuda_dev->stream));
3696 if ((p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY) &&
3697 (p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM))
3702 return vulkan_transfer_data_to_cuda(hwfc, dst,
src);