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)
83 #ifdef VK_KHR_shader_expect_assume
84 VkPhysicalDeviceShaderExpectAssumeFeaturesKHR expect_assume;
88 #ifdef VK_KHR_video_maintenance2
89 VkPhysicalDeviceVideoMaintenance2FeaturesKHR video_maintenance_2;
99 #ifdef VK_KHR_shader_relaxed_extended_instruction
100 VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR relaxed_extended_instruction;
120 VkPhysicalDeviceExternalMemoryHostPropertiesEXT
hprops;
195 feats->
device = (VkPhysicalDeviceFeatures2) {
196 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
200 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES);
202 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES);
204 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES);
207 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES);
209 #ifdef VK_KHR_shader_expect_assume
211 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES_KHR);
215 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR);
216 #ifdef VK_KHR_video_maintenance2
218 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR);
222 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);
224 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR);
226 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT);
228 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT);
230 #ifdef VK_KHR_shader_relaxed_extended_instruction
232 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR);
236 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV);
242 #define COPY_VAL(VAL) \
244 dst->VAL = src->VAL; \
247 COPY_VAL(device.features.shaderImageGatherExtended);
248 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
249 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
250 COPY_VAL(device.features.fragmentStoresAndAtomics);
251 COPY_VAL(device.features.vertexPipelineStoresAndAtomics);
252 COPY_VAL(device.features.shaderInt64);
253 COPY_VAL(device.features.shaderInt16);
254 COPY_VAL(device.features.shaderFloat64);
255 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
256 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
258 COPY_VAL(vulkan_1_1.samplerYcbcrConversion);
259 COPY_VAL(vulkan_1_1.storagePushConstant16);
260 COPY_VAL(vulkan_1_1.storageBuffer16BitAccess);
261 COPY_VAL(vulkan_1_1.uniformAndStorageBuffer16BitAccess);
263 COPY_VAL(vulkan_1_2.timelineSemaphore);
264 COPY_VAL(vulkan_1_2.scalarBlockLayout);
265 COPY_VAL(vulkan_1_2.bufferDeviceAddress);
266 COPY_VAL(vulkan_1_2.hostQueryReset);
267 COPY_VAL(vulkan_1_2.storagePushConstant8);
269 COPY_VAL(vulkan_1_2.storageBuffer8BitAccess);
270 COPY_VAL(vulkan_1_2.uniformAndStorageBuffer8BitAccess);
272 COPY_VAL(vulkan_1_2.shaderBufferInt64Atomics);
273 COPY_VAL(vulkan_1_2.shaderSharedInt64Atomics);
274 COPY_VAL(vulkan_1_2.vulkanMemoryModel);
275 COPY_VAL(vulkan_1_2.vulkanMemoryModelDeviceScope);
277 COPY_VAL(vulkan_1_3.dynamicRendering);
279 COPY_VAL(vulkan_1_3.synchronization2);
280 COPY_VAL(vulkan_1_3.computeFullSubgroups);
281 COPY_VAL(vulkan_1_3.subgroupSizeControl);
282 COPY_VAL(vulkan_1_3.shaderZeroInitializeWorkgroupMemory);
283 COPY_VAL(vulkan_1_3.dynamicRendering);
285 COPY_VAL(timeline_semaphore.timelineSemaphore);
287 COPY_VAL(video_maintenance_1.videoMaintenance1);
288 #ifdef VK_KHR_video_maintenance2
289 COPY_VAL(video_maintenance_2.videoMaintenance2);
292 COPY_VAL(shader_object.shaderObject);
294 COPY_VAL(cooperative_matrix.cooperativeMatrix);
296 COPY_VAL(descriptor_buffer.descriptorBuffer);
297 COPY_VAL(descriptor_buffer.descriptorBufferPushDescriptors);
299 COPY_VAL(atomic_float.shaderBufferFloat32Atomics);
300 COPY_VAL(atomic_float.shaderBufferFloat32AtomicAdd);
302 #ifdef VK_KHR_shader_relaxed_extended_instruction
303 COPY_VAL(relaxed_extended_instruction.shaderRelaxedExtendedInstruction);
306 #ifdef VK_KHR_shader_expect_assume
307 COPY_VAL(expect_assume.shaderExpectAssume);
314 #define ASPECT_2PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT)
315 #define ASPECT_3PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)
327 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_GRAY8, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8_UNORM } },
328 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
329 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY12, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
330 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY14, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
331 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
332 { VK_FORMAT_R32_UINT,
AV_PIX_FMT_GRAY32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_UINT } },
333 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GRAYF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_SFLOAT } },
336 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_BGRA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
337 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGBA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
338 { VK_FORMAT_R8G8B8_UNORM,
AV_PIX_FMT_RGB24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8_UNORM } },
339 { VK_FORMAT_B8G8R8_UNORM,
AV_PIX_FMT_BGR24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8_UNORM } },
340 { VK_FORMAT_R16G16B16_UNORM,
AV_PIX_FMT_RGB48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16_UNORM } },
341 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_RGBA64, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
342 { VK_FORMAT_R5G6B5_UNORM_PACK16,
AV_PIX_FMT_RGB565, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R5G6B5_UNORM_PACK16 } },
343 { VK_FORMAT_B5G6R5_UNORM_PACK16,
AV_PIX_FMT_BGR565, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B5G6R5_UNORM_PACK16 } },
344 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_BGR0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
345 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGB0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
346 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_X2RGB10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
347 { VK_FORMAT_A2B10G10R10_UNORM_PACK32,
AV_PIX_FMT_X2BGR10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2B10G10R10_UNORM_PACK32 } },
348 { VK_FORMAT_R32G32B32_SFLOAT,
AV_PIX_FMT_RGBF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_SFLOAT } },
349 { VK_FORMAT_R32G32B32A32_SFLOAT,
AV_PIX_FMT_RGBAF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_SFLOAT } },
350 { VK_FORMAT_R32G32B32_UINT,
AV_PIX_FMT_RGB96, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_UINT } },
351 { VK_FORMAT_R32G32B32A32_UINT,
AV_PIX_FMT_RGBA128, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_UINT } },
354 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_GBRP, VK_IMAGE_ASPECT_COLOR_BIT, 3, 3, 3, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } },
355 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GBRP10, VK_IMAGE_ASPECT_COLOR_BIT, 3, 3, 3, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
356 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GBRP12, VK_IMAGE_ASPECT_COLOR_BIT, 3, 3, 3, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
357 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GBRP14, VK_IMAGE_ASPECT_COLOR_BIT, 3, 3, 3, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
358 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GBRP16, VK_IMAGE_ASPECT_COLOR_BIT, 3, 3, 3, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
359 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GBRPF32, VK_IMAGE_ASPECT_COLOR_BIT, 3, 3, 3, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } },
362 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_GBRAP, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } },
363 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GBRAP10, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
364 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GBRAP12, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
365 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GBRAP14, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
366 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GBRAP16, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
367 { VK_FORMAT_R32_UINT,
AV_PIX_FMT_GBRAP32, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R32_UINT, VK_FORMAT_R32_UINT, VK_FORMAT_R32_UINT, VK_FORMAT_R32_UINT } },
368 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GBRAPF32, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } },
372 { 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 } },
373 { 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 } },
378 { 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 } },
379 { 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 } },
384 { 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 } },
385 { 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 } },
403 { VK_FORMAT_G8B8G8R8_422_UNORM,
AV_PIX_FMT_YUYV422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
404 { VK_FORMAT_B8G8R8G8_422_UNORM,
AV_PIX_FMT_UYVY422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
405 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
AV_PIX_FMT_Y210, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
406 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
AV_PIX_FMT_Y212, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
407 { VK_FORMAT_G16B16G16R16_422_UNORM,
AV_PIX_FMT_Y216, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
410 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_UYVA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
411 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_XV30, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
412 { VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
AV_PIX_FMT_XV36, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
413 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_XV48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
434 VkImageTiling tiling,
437 VkImageAspectFlags *
aspect,
438 VkImageUsageFlags *supported_usage,
439 int disable_multiplane,
int need_storage)
445 const VkFormatFeatureFlagBits2 basic_flags = VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
446 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
447 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
451 VkFormatProperties3 fprops = {
452 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3,
454 VkFormatProperties2 prop = {
455 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
458 VkFormatFeatureFlagBits2 feats_primary, feats_secondary;
459 int basics_primary = 0, basics_secondary = 0;
460 int storage_primary = 0, storage_secondary = 0;
462 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
466 feats_primary = tiling == VK_IMAGE_TILING_LINEAR ?
467 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
468 basics_primary = (feats_primary & basic_flags) == basic_flags;
469 storage_primary = !!(feats_primary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
472 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
475 feats_secondary = tiling == VK_IMAGE_TILING_LINEAR ?
476 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
477 basics_secondary = (feats_secondary & basic_flags) == basic_flags;
478 storage_secondary = !!(feats_secondary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
480 basics_secondary = basics_primary;
481 storage_secondary = storage_primary;
484 if (basics_primary &&
486 (!need_storage || (need_storage && (storage_primary | storage_secondary)))) {
501 ((need_storage && (storage_primary | storage_secondary)) ?
502 VK_IMAGE_USAGE_STORAGE_BIT : 0);
504 }
else if (basics_secondary &&
505 (!need_storage || (need_storage && storage_secondary))) {
526 #if CONFIG_VULKAN_STATIC
527 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance,
536 #if CONFIG_VULKAN_STATIC
539 static const char *lib_names[] = {
542 #elif defined(__APPLE__)
553 p->
libvulkan = dlopen(lib_names[
i], RTLD_NOW | RTLD_LOCAL);
591 #ifdef VK_KHR_shader_expect_assume
595 #ifdef VK_KHR_video_maintenance2
621 static VkBool32 VKAPI_CALL
vk_dbg_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
622 VkDebugUtilsMessageTypeFlagsEXT messageType,
623 const VkDebugUtilsMessengerCallbackDataEXT *
data,
630 switch (
data->messageIdNumber) {
641 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: l =
AV_LOG_VERBOSE;
break;
642 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: l =
AV_LOG_INFO;
break;
643 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: l =
AV_LOG_WARNING;
break;
644 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: l =
AV_LOG_ERROR;
break;
649 for (
int i = 0;
i <
data->cmdBufLabelCount;
i++)
655 #define ADD_VAL_TO_LIST(list, count, val) \
657 list = av_realloc_array(list, sizeof(*list), ++count); \
659 err = AVERROR(ENOMEM); \
662 list[count - 1] = av_strdup(val); \
663 if (!list[count - 1]) { \
664 err = AVERROR(ENOMEM); \
669 #define RELEASE_PROPS(props, count) \
671 for (int i = 0; i < count; i++) \
672 av_free((void *)((props)[i])); \
673 av_free((void *)props); \
691 const char *
const **
dst, uint32_t *num,
695 const char **extension_names =
NULL;
699 int err = 0, found, extensions_found = 0;
702 int optional_exts_num;
703 uint32_t sup_ext_count;
704 char *user_exts_str =
NULL;
706 VkExtensionProperties *sup_ext;
716 if (!user_exts_str) {
721 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count,
NULL);
722 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
725 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count, sup_ext);
733 if (!user_exts_str) {
738 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
739 &sup_ext_count,
NULL);
740 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
743 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
744 &sup_ext_count, sup_ext);
747 for (
int i = 0;
i < optional_exts_num;
i++) {
748 tstr = optional_exts[
i].
name;
752 if (p->
dprops.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA &&
753 !strcmp(tstr, VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME))
760 !strcmp(tstr, VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME)) {
764 for (
int j = 0; j < sup_ext_count; j++) {
765 if (!strcmp(tstr, sup_ext[j].extensionName)) {
782 tstr = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
784 for (
int j = 0; j < sup_ext_count; j++) {
785 if (!strcmp(tstr, sup_ext[j].extensionName)) {
801 #ifdef VK_KHR_shader_relaxed_extended_instruction
804 tstr = VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME;
806 for (
int j = 0; j < sup_ext_count; j++) {
807 if (!strcmp(tstr, sup_ext[j].extensionName)) {
825 char *save, *token =
av_strtok(user_exts_str,
"+", &save);
828 for (
int j = 0; j < sup_ext_count; j++) {
829 if (!strcmp(token, sup_ext[j].extensionName)) {
845 *
dst = extension_names;
846 *num = extensions_found;
860 const char *
const **
dst, uint32_t *num,
867 static const char layer_standard_validation[] = {
"VK_LAYER_KHRONOS_validation" };
868 int layer_standard_validation_found = 0;
870 uint32_t sup_layer_count;
871 VkLayerProperties *sup_layers;
874 char *user_layers_str =
NULL;
877 const char **enabled_layers =
NULL;
878 uint32_t enabled_layers_count = 0;
886 vk->EnumerateInstanceLayerProperties(&sup_layer_count,
NULL);
887 sup_layers =
av_malloc_array(sup_layer_count,
sizeof(VkLayerProperties));
890 vk->EnumerateInstanceLayerProperties(&sup_layer_count, sup_layers);
893 for (
int i = 0;
i < sup_layer_count;
i++)
897 if (!debug_opt && !user_layers)
902 if (!strcmp(debug_opt->
value,
"profile")) {
904 }
else if (!strcmp(debug_opt->
value,
"printf")) {
906 }
else if (!strcmp(debug_opt->
value,
"validate")) {
908 }
else if (!strcmp(debug_opt->
value,
"practices")) {
911 char *end_ptr =
NULL;
912 int idx = strtol(debug_opt->
value, &end_ptr, 10);
913 if (end_ptr == debug_opt->
value || end_ptr[0] !=
'\0' ||
928 for (
int i = 0;
i < sup_layer_count;
i++) {
929 if (!strcmp(layer_standard_validation, sup_layers[
i].layerName)) {
931 layer_standard_validation);
932 ADD_VAL_TO_LIST(enabled_layers, enabled_layers_count, layer_standard_validation);
934 layer_standard_validation_found = 1;
938 if (!layer_standard_validation_found) {
940 "Validation Layer \"%s\" not supported\n", layer_standard_validation);
953 if (!user_layers_str) {
958 token =
av_strtok(user_layers_str,
"+", &save);
963 if (!strcmp(layer_standard_validation, token) && layer_standard_validation_found) {
969 for (
int j = 0; j < sup_layer_count; j++) {
970 if (!strcmp(token, sup_layers[j].layerName)) {
981 if (!strcmp(layer_standard_validation, token))
985 "Layer \"%s\" not supported\n", token);
1002 *
dst = enabled_layers;
1003 *num = enabled_layers_count;
1018 VkApplicationInfo application_info = {
1019 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
1020 .pApplicationName =
"ffmpeg",
1024 .pEngineName =
"libavutil",
1025 .apiVersion = VK_API_VERSION_1_3,
1030 VkValidationFeaturesEXT validation_features = {
1031 .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
1033 VkInstanceCreateInfo inst_props = {
1034 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
1035 .pApplicationInfo = &application_info,
1051 &inst_props.enabledLayerCount, debug_mode);
1057 &inst_props.enabledExtensionCount, *debug_mode);
1065 static const VkValidationFeatureEnableEXT feat_list_validate[] = {
1066 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1067 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1068 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
1070 validation_features.pEnabledValidationFeatures = feat_list_validate;
1071 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_validate);
1072 inst_props.pNext = &validation_features;
1074 static const VkValidationFeatureEnableEXT feat_list_debug[] = {
1075 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1076 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1077 VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT,
1079 validation_features.pEnabledValidationFeatures = feat_list_debug;
1080 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_debug);
1081 inst_props.pNext = &validation_features;
1083 static const VkValidationFeatureEnableEXT feat_list_practices[] = {
1084 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1085 VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT,
1087 validation_features.pEnabledValidationFeatures = feat_list_practices;
1088 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_practices);
1089 inst_props.pNext = &validation_features;
1093 for (
int i = 0;
i < inst_props.enabledExtensionCount;
i++) {
1094 if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
1095 inst_props.ppEnabledExtensionNames[
i])) {
1096 inst_props.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
1103 ret = vk->CreateInstance(&inst_props, hwctx->
alloc, &hwctx->
inst);
1106 if (
ret != VK_SUCCESS) {
1123 VkDebugUtilsMessengerCreateInfoEXT dbg = {
1124 .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
1125 .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
1126 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
1127 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
1128 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
1129 .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
1130 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
1131 VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
1136 vk->CreateDebugUtilsMessengerEXT(hwctx->
inst, &dbg,
1143 RELEASE_PROPS(inst_props.ppEnabledLayerNames, inst_props.enabledLayerCount);
1162 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
return "integrated";
1163 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
return "discrete";
1164 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
return "virtual";
1165 case VK_PHYSICAL_DEVICE_TYPE_CPU:
return "software";
1166 default:
return "unknown";
1173 int err = 0, choice = -1;
1179 VkPhysicalDevice *devices =
NULL;
1180 VkPhysicalDeviceIDProperties *idp =
NULL;
1181 VkPhysicalDeviceProperties2 *prop =
NULL;
1182 VkPhysicalDeviceDriverProperties *driver_prop =
NULL;
1183 VkPhysicalDeviceDrmPropertiesEXT *drm_prop =
NULL;
1185 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num,
NULL);
1186 if (
ret != VK_SUCCESS || !num) {
1195 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num, devices);
1196 if (
ret != VK_SUCCESS) {
1215 driver_prop =
av_calloc(num,
sizeof(*driver_prop));
1222 drm_prop =
av_calloc(num,
sizeof(*drm_prop));
1230 for (
int i = 0;
i < num;
i++) {
1232 drm_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT;
1233 driver_prop[
i].pNext = &drm_prop[
i];
1235 driver_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
1236 idp[
i].pNext = &driver_prop[
i];
1237 idp[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
1238 prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1239 prop[
i].pNext = &idp[
i];
1241 vk->GetPhysicalDeviceProperties2(devices[
i], &prop[
i]);
1243 prop[
i].properties.deviceName,
1245 prop[
i].properties.deviceID);
1249 for (
int i = 0;
i < num;
i++) {
1250 if (!strncmp(idp[
i].deviceUUID, select->
uuid, VK_UUID_SIZE)) {
1259 for (
int i = 0;
i < num;
i++) {
1260 if ((select->
drm_major == drm_prop[
i].primaryMajor &&
1261 select->
drm_minor == drm_prop[
i].primaryMinor) ||
1262 (select->
drm_major == drm_prop[
i].renderMajor &&
1263 select->
drm_minor == drm_prop[
i].renderMinor)) {
1272 }
else if (select->
name) {
1274 for (
int i = 0;
i < num;
i++) {
1275 if (strstr(prop[
i].properties.deviceName, select->
name)) {
1286 for (
int i = 0;
i < num;
i++) {
1287 if (select->
pci_device == prop[
i].properties.deviceID) {
1298 for (
int i = 0;
i < num;
i++) {
1299 if (select->
vendor_id == prop[
i].properties.vendorID) {
1309 if (select->
index < num) {
1310 choice = select->
index;
1322 choice, prop[choice].properties.deviceName,
1324 prop[choice].properties.deviceID);
1326 p->
props = prop[choice];
1328 p->
dprops = driver_prop[choice];
1343 VkQueueFlagBits
flags)
1346 uint32_t min_score = UINT32_MAX;
1348 for (
int i = 0;
i < num_qf;
i++) {
1349 VkQueueFlagBits qflags = qf[
i].queueFamilyProperties.queueFlags;
1352 if ((
flags & VK_QUEUE_TRANSFER_BIT) &&
1353 (qflags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)))
1354 qflags |= VK_QUEUE_TRANSFER_BIT;
1356 if (qflags &
flags) {
1357 uint32_t score =
av_popcount(qflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1358 if (score < min_score) {
1366 qf[
index].queueFamilyProperties.timestampValidBits++;
1372 VkQueueFamilyVideoPropertiesKHR *qf_vid, uint32_t num_qf,
1373 VkVideoCodecOperationFlagBitsKHR
flags)
1376 uint32_t min_score = UINT32_MAX;
1378 for (
int i = 0;
i < num_qf;
i++) {
1379 const VkQueueFlagBits qflags = qf[
i].queueFamilyProperties.queueFlags;
1380 const VkQueueFlagBits vflags = qf_vid[
i].videoCodecOperations;
1382 if (!(qflags & (VK_QUEUE_VIDEO_ENCODE_BIT_KHR | VK_QUEUE_VIDEO_DECODE_BIT_KHR)))
1385 if (vflags &
flags) {
1386 uint32_t score =
av_popcount(vflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1387 if (score < min_score) {
1395 qf[
index].queueFamilyProperties.timestampValidBits++;
1407 VkQueueFamilyProperties2 *qf =
NULL;
1408 VkQueueFamilyVideoPropertiesKHR *qf_vid =
NULL;
1411 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &num,
NULL);
1422 qf_vid =
av_malloc_array(num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
1426 for (uint32_t
i = 0;
i < num;
i++) {
1427 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1428 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1430 qf[
i] = (VkQueueFamilyProperties2) {
1431 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
1437 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &num, qf);
1440 for (
int i = 0;
i < num;
i++) {
1442 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_GRAPHICS_BIT) ?
" graphics" :
"",
1443 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_COMPUTE_BIT) ?
" compute" :
"",
1444 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_TRANSFER_BIT) ?
" transfer" :
"",
1445 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ?
" encode" :
"",
1446 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_DECODE_BIT_KHR) ?
" decode" :
"",
1447 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_SPARSE_BINDING_BIT) ?
" sparse" :
"",
1448 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_OPTICAL_FLOW_BIT_NV) ?
" optical_flow" :
"",
1449 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_PROTECTED_BIT) ?
" protected" :
"",
1450 qf[
i].queueFamilyProperties.queueCount);
1454 qf[
i].queueFamilyProperties.timestampValidBits = 0;
1460 #define PICK_QF(type, vid_op) \
1466 idx = pick_video_queue_family(qf, qf_vid, num, vid_op); \
1468 idx = pick_queue_family(qf, num, type); \
1473 for (i = 0; i < hwctx->nb_qf; i++) { \
1474 if (hwctx->qf[i].idx == idx) { \
1475 hwctx->qf[i].flags |= type; \
1476 hwctx->qf[i].video_caps |= vid_op; \
1480 if (i == hwctx->nb_qf) { \
1481 hwctx->qf[i].idx = idx; \
1482 hwctx->qf[i].num = qf[idx].queueFamilyProperties.queueCount; \
1483 hwctx->qf[i].flags = type; \
1484 hwctx->qf[i].video_caps = vid_op; \
1489 PICK_QF(VK_QUEUE_GRAPHICS_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1490 PICK_QF(VK_QUEUE_COMPUTE_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1491 PICK_QF(VK_QUEUE_TRANSFER_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1492 PICK_QF(VK_QUEUE_OPTICAL_FLOW_BIT_NV, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1494 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR);
1495 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR);
1497 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR);
1498 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR);
1500 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR);
1508 sizeof(VkDeviceQueueCreateInfo));
1509 if (!cd->pQueueCreateInfos)
1512 for (uint32_t
i = 0;
i < hwctx->
nb_qf;
i++) {
1515 VkDeviceQueueCreateInfo *pc;
1516 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++) {
1517 if (hwctx->
qf[
i].
idx == cd->pQueueCreateInfos[j].queueFamilyIndex) {
1527 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++)
1528 av_free((
void *)cd->pQueueCreateInfos[
i].pQueuePriorities);
1529 av_free((
void *)cd->pQueueCreateInfos);
1533 for (uint32_t j = 0; j < hwctx->
qf[
i].
num; j++)
1536 pc = (VkDeviceQueueCreateInfo *)cd->pQueueCreateInfos;
1537 pc[cd->queueCreateInfoCount++] = (VkDeviceQueueCreateInfo) {
1538 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1539 .queueFamilyIndex = hwctx->
qf[
i].
idx,
1540 .queueCount = hwctx->
qf[
i].
num,
1545 #if FF_API_VULKAN_FIXED_QUEUES
1554 #define SET_OLD_QF(field, nb_field, type) \
1556 if (field < 0 && hwctx->qf[i].flags & type) { \
1557 field = hwctx->qf[i].idx; \
1558 nb_field = hwctx->qf[i].num; \
1562 for (uint32_t
i = 0;
i < hwctx->
nb_qf;
i++) {
1592 vk->DestroyDebugUtilsMessengerEXT(hwctx->
inst, p->
debug_ctx,
1596 vk->DestroyInstance(hwctx->
inst, hwctx->
alloc);
1620 int disable_multiplane,
1631 VkDeviceCreateInfo dev_info = {
1632 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1645 &dev_info.enabledExtensionCount, debug_mode))) {
1646 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1647 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1648 av_free((
void *)dev_info.pQueueCreateInfos);
1654 vk->GetPhysicalDeviceFeatures2(hwctx->
phys_dev, &supported_feats.
device);
1660 dev_info.pEnabledFeatures = &p->
feats.
device.features;
1670 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1671 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1672 av_free((
void *)dev_info.pQueueCreateInfos);
1674 if (
ret != VK_SUCCESS) {
1677 for (
int i = 0;
i < dev_info.enabledExtensionCount;
i++)
1678 av_free((
void *)dev_info.ppEnabledExtensionNames[
i]);
1679 av_free((
void *)dev_info.ppEnabledExtensionNames);
1730 VkQueueFamilyProperties2 *qf;
1731 VkQueueFamilyVideoPropertiesKHR *qf_vid;
1732 VkPhysicalDeviceExternalSemaphoreInfo ext_sem_props_info;
1733 int graph_index, comp_index, tx_index, enc_index, dec_index;
1752 p->
props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1754 p->
hprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;
1756 vk->GetPhysicalDeviceProperties2(hwctx->
phys_dev, &p->
props);
1758 p->
props.properties.deviceName);
1761 p->
props.properties.limits.optimalBufferCopyRowPitchAlignment);
1763 p->
props.properties.limits.minMemoryMapAlignment);
1765 p->
props.properties.limits.nonCoherentAtomSize);
1768 p->
hprops.minImportedHostPointerAlignment);
1772 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &qf_num,
NULL);
1778 ext_sem_props_info = (VkPhysicalDeviceExternalSemaphoreInfo) {
1779 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
1783 ext_sem_props_info.handleType =
1785 IsWindows8OrGreater()
1786 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
1787 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
1789 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
1792 vk->GetPhysicalDeviceExternalSemaphoreProperties(hwctx->
phys_dev,
1793 &ext_sem_props_info,
1800 qf_vid =
av_malloc_array(qf_num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
1806 for (uint32_t
i = 0;
i < qf_num;
i++) {
1807 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1808 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1810 qf[
i] = (VkQueueFamilyProperties2) {
1811 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
1816 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &qf_num, qf);
1825 for (uint32_t
i = 0;
i < qf_num;
i++) {
1832 for (uint32_t j = 0; j < qf[
i].queueFamilyProperties.queueCount; j++) {
1843 #if FF_API_VULKAN_FIXED_QUEUES
1851 #define CHECK_QUEUE(type, required, fidx, ctx_qf, qc) \
1853 if (ctx_qf < 0 && required) { \
1854 av_log(ctx, AV_LOG_ERROR, "%s queue family is required, but marked as missing" \
1855 " in the context!\n", type); \
1856 err = AVERROR(EINVAL); \
1858 } else if (fidx < 0 || ctx_qf < 0) { \
1860 } else if (ctx_qf >= qf_num) { \
1861 av_log(ctx, AV_LOG_ERROR, "Invalid %s family index %i (device has %i families)!\n", \
1862 type, ctx_qf, qf_num); \
1863 err = AVERROR(EINVAL); \
1867 av_log(ctx, AV_LOG_VERBOSE, "Using queue family %i (queues: %i)" \
1868 " for%s%s%s%s%s\n", \
1870 ctx_qf == graph_index ? " graphics" : "", \
1871 ctx_qf == comp_index ? " compute" : "", \
1872 ctx_qf == tx_index ? " transfers" : "", \
1873 ctx_qf == enc_index ? " encode" : "", \
1874 ctx_qf == dec_index ? " decode" : ""); \
1875 graph_index = (ctx_qf == graph_index) ? -1 : graph_index; \
1876 comp_index = (ctx_qf == comp_index) ? -1 : comp_index; \
1877 tx_index = (ctx_qf == tx_index) ? -1 : tx_index; \
1878 enc_index = (ctx_qf == enc_index) ? -1 : enc_index; \
1879 dec_index = (ctx_qf == dec_index) ? -1 : dec_index; \
1892 if (!hwctx->
nb_qf) {
1893 #define ADD_QUEUE(ctx_qf, qc, flag) \
1895 if (ctx_qf != -1) { \
1896 hwctx->qf[hwctx->nb_qf++] = (AVVulkanDeviceQueueFamily) { \
1914 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
1916 hwctx->
qf[
i].
flags & (VK_QUEUE_VIDEO_DECODE_BIT_KHR |
1917 VK_QUEUE_VIDEO_ENCODE_BIT_KHR)) {
1924 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
1928 for (
int j = (
i - 1); j >= 0; j--) {
1944 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->
mprops);
1963 if (device && device[0]) {
1965 dev_select.
index = strtol(device, &end, 10);
1966 if (end == device) {
1967 dev_select.
index = 0;
1968 dev_select.
name = device;
1984 switch(src_ctx->
type) {
1988 VADisplay dpy = src_hwctx->
display;
1989 #if VA_CHECK_VERSION(1, 15, 0)
1991 VADisplayAttribute attr = {
1992 .type = VADisplayPCIID,
1997 #if VA_CHECK_VERSION(1, 15, 0)
1998 vas = vaGetDisplayAttributes(dpy, &attr, 1);
1999 if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED)
2000 dev_select.pci_device = (attr.value & 0xFFFF);
2003 if (!dev_select.pci_device) {
2004 vendor = vaQueryVendorString(dpy);
2010 if (strstr(vendor,
"AMD"))
2011 dev_select.vendor_id = 0x1002;
2020 struct stat drm_node_info;
2021 drmDevice *drm_dev_info;
2024 err = fstat(src_hwctx->
fd, &drm_node_info);
2031 dev_select.drm_major = major(drm_node_info.st_dev);
2032 dev_select.drm_minor = minor(drm_node_info.st_dev);
2033 dev_select.has_drm = 1;
2035 err = drmGetDevice(src_hwctx->
fd, &drm_dev_info);
2042 if (drm_dev_info->bustype == DRM_BUS_PCI)
2043 dev_select.pci_device = drm_dev_info->deviceinfo.pci->device_id;
2045 drmFreeDevice(&drm_dev_info);
2055 CudaFunctions *cu = cu_internal->
cuda_dl;
2057 int ret =
CHECK_CU(cu->cuDeviceGetUuid((CUuuid *)&dev_select.uuid,
2064 dev_select.has_uuid = 1;
2079 const void *hwconfig,
2088 VK_IMAGE_TILING_OPTIMAL,
2101 VK_IMAGE_TILING_OPTIMAL,
2111 constraints->
max_width = p->
props.properties.limits.maxImageDimension2D;
2112 constraints->
max_height = p->
props.properties.limits.maxImageDimension2D;
2125 VkMemoryPropertyFlagBits req_flags,
const void *alloc_extension,
2126 VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
2133 VkMemoryAllocateInfo alloc_info = {
2134 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2135 .pNext = alloc_extension,
2136 .allocationSize = req->size,
2141 for (
int i = 0;
i < p->
mprops.memoryTypeCount;
i++) {
2142 const VkMemoryType *
type = &p->
mprops.memoryTypes[
i];
2145 if (!(req->memoryTypeBits & (1 <<
i)))
2149 if ((
type->propertyFlags & req_flags) != req_flags)
2153 if (req->size > p->
mprops.memoryHeaps[
type->heapIndex].size)
2167 alloc_info.memoryTypeIndex =
index;
2169 ret = vk->AllocateMemory(dev_hwctx->
act_dev, &alloc_info,
2170 dev_hwctx->
alloc, mem);
2171 if (
ret != VK_SUCCESS) {
2177 *mem_flags |= p->
mprops.memoryTypes[
index].propertyFlags;
2187 if (internal->cuda_fc_ref) {
2193 CudaFunctions *cu = cu_internal->
cuda_dl;
2196 if (internal->cu_sem[
i])
2197 CHECK_CU(cu->cuDestroyExternalSemaphore(internal->cu_sem[
i]));
2198 if (internal->cu_mma[
i])
2199 CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[
i]));
2200 if (internal->ext_mem[
i])
2201 CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[
i]));
2203 if (internal->ext_sem_handle[
i])
2204 CloseHandle(internal->ext_sem_handle[
i]);
2205 if (internal->ext_mem_handle[
i])
2206 CloseHandle(internal->ext_mem_handle[
i]);
2231 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
2233 .pSemaphores =
f->sem,
2234 .pValues =
f->sem_value,
2235 .semaphoreCount = nb_sems,
2243 for (
int i = 0;
i < nb_images;
i++) {
2258 void *alloc_pnext,
size_t alloc_pnext_stride)
2260 int img_cnt = 0, err;
2268 while (
f->img[img_cnt]) {
2270 VkImageMemoryRequirementsInfo2 req_desc = {
2271 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
2272 .image =
f->img[img_cnt],
2274 VkMemoryDedicatedAllocateInfo ded_alloc = {
2275 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
2276 .pNext = (
void *)(((uint8_t *)alloc_pnext) + img_cnt*alloc_pnext_stride),
2278 VkMemoryDedicatedRequirements ded_req = {
2279 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
2281 VkMemoryRequirements2 req = {
2282 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
2286 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req);
2288 if (
f->tiling == VK_IMAGE_TILING_LINEAR)
2289 req.memoryRequirements.size =
FFALIGN(req.memoryRequirements.size,
2290 p->
props.properties.limits.minMemoryMapAlignment);
2293 use_ded_mem = ded_req.prefersDedicatedAllocation |
2294 ded_req.requiresDedicatedAllocation;
2296 ded_alloc.image =
f->img[img_cnt];
2300 f->tiling == VK_IMAGE_TILING_LINEAR ?
2301 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
2302 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2303 use_ded_mem ? &ded_alloc : (
void *)ded_alloc.pNext,
2304 &
f->flags, &
f->mem[img_cnt])))
2307 f->size[img_cnt] = req.memoryRequirements.size;
2308 bind_info[img_cnt].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
2309 bind_info[img_cnt].image =
f->img[img_cnt];
2310 bind_info[img_cnt].memory =
f->mem[img_cnt];
2316 ret = vk->BindImageMemory2(hwctx->
act_dev, img_cnt, bind_info);
2317 if (
ret != VK_SUCCESS) {
2345 uint32_t dst_qf = VK_QUEUE_FAMILY_IGNORED;
2346 VkImageLayout new_layout;
2347 VkAccessFlags2 new_access;
2348 VkPipelineStageFlagBits2 src_stage = VK_PIPELINE_STAGE_2_NONE;
2354 .
data = (uint8_t *)hwfc,
2358 .hw_frames_ctx = &tmp_ref,
2361 VkCommandBuffer cmd_buf;
2363 cmd_buf = exec->
buf;
2367 VK_PIPELINE_STAGE_2_NONE,
2368 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
2374 new_layout = VK_IMAGE_LAYOUT_GENERAL;
2375 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2378 new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
2379 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2382 new_layout = VK_IMAGE_LAYOUT_GENERAL;
2383 new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2386 new_layout = VK_IMAGE_LAYOUT_GENERAL;
2387 new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2388 dst_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR;
2389 src_stage = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
2392 new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR;
2393 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2396 new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR;
2397 new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2400 new_layout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR;
2401 new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2407 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
2408 new_access, new_layout, dst_qf);
2410 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
2411 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
2412 .pImageMemoryBarriers = img_bar,
2413 .imageMemoryBarrierCount = nb_img_bar,
2427 int frame_w,
int frame_h,
int plane)
2444 VkImageTiling tiling, VkImageUsageFlagBits
usage,
2445 VkImageCreateFlags
flags,
int nb_layers,
2457 VkSemaphoreTypeCreateInfo sem_type_info = {
2458 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2459 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2462 VkSemaphoreCreateInfo sem_spawn = {
2463 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2464 .pNext = &sem_type_info,
2467 VkExportSemaphoreCreateInfo ext_sem_info_opaque = {
2468 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
2470 .handleTypes = IsWindows8OrGreater()
2471 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2472 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
2474 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
2479 if (p->
ext_sem_props_opaque.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) {
2493 for (
int i = 0; (hwfc_vk->
format[
i] != VK_FORMAT_UNDEFINED);
i++) {
2494 VkImageCreateInfo create_info = {
2495 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2496 .pNext = create_pnext,
2497 .imageType = VK_IMAGE_TYPE_2D,
2501 .arrayLayers = nb_layers,
2504 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2506 .samples = VK_SAMPLE_COUNT_1_BIT,
2507 .pQueueFamilyIndices = p->
img_qfs,
2509 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2510 VK_SHARING_MODE_EXCLUSIVE,
2513 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
2516 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
2518 if (
ret != VK_SUCCESS) {
2526 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
2528 if (
ret != VK_SUCCESS) {
2536 f->layout[
i] = create_info.initialLayout;
2538 f->sem_value[
i] = 0;
2554 VkExternalMemoryHandleTypeFlags *comp_handle_types,
2555 VkExternalMemoryHandleTypeFlagBits *iexp,
2556 VkExternalMemoryHandleTypeFlagBits
exp)
2564 const VkImageDrmFormatModifierListCreateInfoEXT *drm_mod_info =
2566 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
2567 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && drm_mod_info;
2570 VkExternalImageFormatProperties eprops = {
2571 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
2573 VkImageFormatProperties2 props = {
2574 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
2577 VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
2578 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
2580 .pQueueFamilyIndices = p->
img_qfs,
2582 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2583 VK_SHARING_MODE_EXCLUSIVE,
2585 VkPhysicalDeviceExternalImageFormatInfo enext = {
2586 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
2588 .pNext = has_mods ? &phy_dev_mod_info :
NULL,
2590 VkPhysicalDeviceImageFormatInfo2 pinfo = {
2591 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
2592 .pNext = !
exp ?
NULL : &enext,
2594 .type = VK_IMAGE_TYPE_2D,
2596 .usage = hwctx->
usage,
2597 .flags = VK_IMAGE_CREATE_ALIAS_BIT,
2600 nb_mods = has_mods ? drm_mod_info->drmFormatModifierCount : 1;
2601 for (
int i = 0;
i < nb_mods;
i++) {
2603 phy_dev_mod_info.drmFormatModifier = drm_mod_info->pDrmFormatModifiers[
i];
2605 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
2608 if (
ret == VK_SUCCESS) {
2610 *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes;
2624 VkExternalMemoryHandleTypeFlags e = 0x0;
2627 VkExternalMemoryImageCreateInfo eiinfo = {
2628 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
2635 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
2636 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
2640 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
2645 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
2648 eminfo[
i].sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
2650 eminfo[
i].handleTypes = e;
2663 if ( (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2664 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR))
2666 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)
2668 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR)
2670 else if (hwctx->
usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)
2724 VkImageUsageFlagBits supported_usage;
2735 (hwctx->
tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
2736 hwctx->
tiling = VK_IMAGE_TILING_LINEAR;
2746 if (hwctx->
format[0] != VK_FORMAT_UNDEFINED) {
2751 "for the current sw_format %s!\n",
2763 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
2772 NULL, &supported_usage,
2775 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
2781 if (!hwctx->
usage) {
2782 hwctx->
usage = supported_usage & (VK_BUFFER_USAGE_TRANSFER_DST_BIT |
2783 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
2784 VK_IMAGE_USAGE_STORAGE_BIT |
2785 VK_IMAGE_USAGE_SAMPLED_BIT);
2788 if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
2791 hwctx->
usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
2798 int is_lone_dpb = ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR) ||
2799 ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2800 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)));
2801 int sampleable = hwctx->
usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
2802 VK_IMAGE_USAGE_STORAGE_BIT);
2803 hwctx->
img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
2804 if (sampleable && !is_lone_dpb) {
2805 hwctx->
img_flags |= VK_IMAGE_CREATE_ALIAS_BIT;
2807 hwctx->
img_flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
2815 if ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
2818 const VkVideoProfileListInfoKHR *pl;
2821 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
2824 for (
i = 0;
i < pl->profileCount;
i++) {
2826 if (pl->pProfiles[
i].videoCodecOperation & 0xFFFF0000)
2829 if (
i == pl->profileCount)
2830 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
2921 static const struct {
2922 uint32_t drm_fourcc;
2924 } vulkan_drm_format_map[] = {
2925 { DRM_FORMAT_R8, VK_FORMAT_R8_UNORM },
2926 { DRM_FORMAT_R16, VK_FORMAT_R16_UNORM },
2927 { DRM_FORMAT_GR88, VK_FORMAT_R8G8_UNORM },
2928 { DRM_FORMAT_RG88, VK_FORMAT_R8G8_UNORM },
2929 { DRM_FORMAT_GR1616, VK_FORMAT_R16G16_UNORM },
2930 { DRM_FORMAT_RG1616, VK_FORMAT_R16G16_UNORM },
2931 { DRM_FORMAT_ARGB8888, VK_FORMAT_B8G8R8A8_UNORM },
2932 { DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM },
2933 { DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM },
2934 { DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM },
2935 { DRM_FORMAT_ARGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
2936 { DRM_FORMAT_ABGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
2937 { DRM_FORMAT_XRGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
2938 { DRM_FORMAT_XBGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
2941 #ifdef DRM_FORMAT_XYUV8888
2942 { DRM_FORMAT_XYUV8888, VK_FORMAT_R8G8B8A8_UNORM },
2943 { DRM_FORMAT_XVYU2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 } ,
2944 { DRM_FORMAT_XVYU12_16161616, VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 } ,
2945 { DRM_FORMAT_XVYU16161616, VK_FORMAT_R16G16B16A16_UNORM } ,
2949 static inline VkFormat drm_to_vulkan_fmt(uint32_t drm_fourcc)
2952 if (vulkan_drm_format_map[
i].drm_fourcc == drm_fourcc)
2953 return vulkan_drm_format_map[
i].vk_format;
2954 return VK_FORMAT_UNDEFINED;
2963 int bind_counts = 0;
2973 if (drm_to_vulkan_fmt(
desc->layers[
i].format) == VK_FORMAT_UNDEFINED) {
2975 desc->layers[
i].format);
2986 f->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
2988 for (
int i = 0;
i <
desc->nb_layers;
i++) {
2992 VkSemaphoreTypeCreateInfo sem_type_info = {
2993 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2994 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2997 VkSemaphoreCreateInfo sem_spawn = {
2998 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2999 .pNext = &sem_type_info,
3004 VkImageDrmFormatModifierExplicitCreateInfoEXT ext_img_mod_spec = {
3005 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
3006 .drmFormatModifier =
desc->objects[0].format_modifier,
3007 .drmFormatModifierPlaneCount =
planes,
3008 .pPlaneLayouts = (
const VkSubresourceLayout *)&ext_img_layouts,
3010 VkExternalMemoryImageCreateInfo ext_img_spec = {
3011 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
3012 .pNext = &ext_img_mod_spec,
3013 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3015 VkImageCreateInfo create_info = {
3016 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3017 .pNext = &ext_img_spec,
3018 .imageType = VK_IMAGE_TYPE_2D,
3019 .format = drm_to_vulkan_fmt(
desc->layers[
i].format),
3024 .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
3025 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
3027 .samples = VK_SAMPLE_COUNT_1_BIT,
3028 .pQueueFamilyIndices = p->
img_qfs,
3030 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3031 VK_SHARING_MODE_EXCLUSIVE,
3035 VkExternalImageFormatProperties ext_props = {
3036 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
3038 VkImageFormatProperties2 props_ret = {
3039 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
3040 .pNext = &ext_props,
3042 VkPhysicalDeviceImageDrmFormatModifierInfoEXT props_drm_mod = {
3043 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
3044 .drmFormatModifier = ext_img_mod_spec.drmFormatModifier,
3045 .pQueueFamilyIndices = create_info.pQueueFamilyIndices,
3046 .queueFamilyIndexCount = create_info.queueFamilyIndexCount,
3047 .sharingMode = create_info.sharingMode,
3049 VkPhysicalDeviceExternalImageFormatInfo props_ext = {
3050 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
3051 .pNext = &props_drm_mod,
3052 .handleType = ext_img_spec.handleTypes,
3054 VkPhysicalDeviceImageFormatInfo2 fmt_props;
3057 create_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT |
3058 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3060 create_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT |
3061 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3063 fmt_props = (VkPhysicalDeviceImageFormatInfo2) {
3064 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3065 .pNext = &props_ext,
3066 .format = create_info.format,
3067 .type = create_info.imageType,
3068 .tiling = create_info.tiling,
3069 .usage = create_info.usage,
3070 .flags = create_info.flags,
3074 ret = vk->GetPhysicalDeviceImageFormatProperties2(hwctx->
phys_dev,
3075 &fmt_props, &props_ret);
3076 if (
ret != VK_SUCCESS) {
3084 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
3088 for (
int j = 0; j <
planes; j++) {
3089 ext_img_layouts[j].offset =
desc->layers[
i].planes[j].offset;
3090 ext_img_layouts[j].rowPitch =
desc->layers[
i].planes[j].pitch;
3091 ext_img_layouts[j].size = 0;
3092 ext_img_layouts[j].arrayPitch = 0;
3093 ext_img_layouts[j].depthPitch = 0;
3097 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
3099 if (
ret != VK_SUCCESS) {
3106 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3108 if (
ret != VK_SUCCESS) {
3115 f->queue_family[
i] = VK_QUEUE_FAMILY_EXTERNAL;
3116 f->layout[
i] = create_info.initialLayout;
3118 f->sem_value[
i] = 0;
3121 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3123 VkImageMemoryRequirementsInfo2 req_desc = {
3124 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
3127 VkMemoryDedicatedRequirements ded_req = {
3128 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
3130 VkMemoryRequirements2 req2 = {
3131 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3136 VkMemoryFdPropertiesKHR fdmp = {
3137 .sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR,
3143 VkImportMemoryFdInfoKHR idesc = {
3144 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
3145 .fd = dup(
desc->objects[
desc->layers[
i].planes[0].object_index].fd),
3146 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3148 VkMemoryDedicatedAllocateInfo ded_alloc = {
3149 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
3151 .image = req_desc.image,
3155 ret = vk->GetMemoryFdPropertiesKHR(hwctx->
act_dev,
3156 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3158 if (
ret != VK_SUCCESS) {
3166 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req2);
3169 req2.memoryRequirements.memoryTypeBits = fdmp.memoryTypeBits;
3172 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
3173 (ded_req.prefersDedicatedAllocation ||
3174 ded_req.requiresDedicatedAllocation) ?
3175 &ded_alloc : ded_alloc.pNext,
3176 &
f->flags, &
f->mem[
i]);
3182 f->size[
i] = req2.memoryRequirements.size;
3185 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3187 for (
int j = 0; j <
planes; j++) {
3188 VkImageAspectFlagBits aspect = j == 0 ? VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT :
3189 j == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3190 VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
3192 plane_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO;
3194 plane_info[bind_counts].planeAspect = aspect;
3196 bind_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
3198 bind_info[bind_counts].image =
f->img[
i];
3199 bind_info[bind_counts].memory =
f->mem[
i];
3202 bind_info[bind_counts].memoryOffset = 0;
3209 ret = vk->BindImageMemory2(hwctx->
act_dev, bind_counts, bind_info);
3210 if (
ret != VK_SUCCESS) {
3240 #ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
3242 VkCommandBuffer cmd_buf;
3248 for (
int i = 0;
i <
desc->nb_objects;
i++) {
3249 VkSemaphoreTypeCreateInfo sem_type_info = {
3250 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3251 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
3253 VkSemaphoreCreateInfo sem_spawn = {
3254 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3255 .pNext = &sem_type_info,
3257 VkImportSemaphoreFdInfoKHR import_info;
3258 struct dma_buf_export_sync_file implicit_fd_info = {
3259 .flags = DMA_BUF_SYNC_READ,
3263 if (ioctl(
desc->objects[
i].fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE,
3264 &implicit_fd_info)) {
3269 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3273 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3274 hwctx->
alloc, &drm_sync_sem[
i]);
3275 if (
ret != VK_SUCCESS) {
3280 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3284 import_info = (VkImportSemaphoreFdInfoKHR) {
3285 .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
3286 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
3287 .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
3288 .semaphore = drm_sync_sem[
i],
3289 .fd = implicit_fd_info.fd,
3292 ret = vk->ImportSemaphoreFdKHR(hwctx->
act_dev, &import_info);
3293 if (
ret != VK_SUCCESS) {
3298 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3304 cmd_buf = exec->
buf;
3310 drm_sync_sem,
desc->nb_objects,
3311 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 1);
3316 VK_PIPELINE_STAGE_2_NONE,
3317 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
3322 VK_PIPELINE_STAGE_2_NONE,
3323 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
3325 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT : 0x0) |
3327 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT : 0x0),
3328 VK_IMAGE_LAYOUT_GENERAL,
3329 VK_QUEUE_FAMILY_IGNORED);
3331 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
3332 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
3333 .pImageMemoryBarriers = img_bar,
3334 .imageMemoryBarrierCount = nb_img_bar,
3345 "image may be corrupted.\n");
3360 if ((err = vulkan_map_from_drm_frame_desc(hwfc, &
f,
src,
flags)))
3364 dst->data[0] = (uint8_t *)
f;
3366 dst->height =
src->height;
3369 &vulkan_unmap_from_drm,
f);
3373 err = vulkan_map_from_drm_frame_sync(hwfc,
dst,
src,
flags);
3396 VASurfaceID surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
3402 vaSyncSurface(vaapi_ctx->display, surface_id);
3410 err = vulkan_map_from_drm(dst_fc,
dst,
tmp,
flags);
3427 VkDeviceMemory mem,
size_t size)
3435 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3436 .type = IsWindows8OrGreater()
3437 ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
3438 : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT,
3441 VkMemoryGetWin32HandleInfoKHR export_info = {
3442 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
3444 .handleType = IsWindows8OrGreater()
3445 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
3446 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
3449 ret = vk->GetMemoryWin32HandleKHR(hwctx->
act_dev, &export_info,
3450 &ext_desc.handle.win32.handle);
3451 if (
ret != VK_SUCCESS) {
3456 dst_int->ext_mem_handle[idx] = ext_desc.handle.win32.handle;
3458 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3459 .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
3462 VkMemoryGetFdInfoKHR export_info = {
3463 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
3465 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
3468 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
3469 &ext_desc.handle.fd);
3470 if (
ret != VK_SUCCESS) {
3477 ret =
CHECK_CU(cu->cuImportExternalMemory(&dst_int->ext_mem[idx], &ext_desc));
3480 close(ext_desc.handle.fd);
3499 VkSemaphoreGetWin32HandleInfoKHR sem_export = {
3500 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
3502 .handleType = IsWindows8OrGreater()
3503 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
3504 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
3506 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3510 VkSemaphoreGetFdInfoKHR sem_export = {
3511 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
3513 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
3515 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3521 ret = vk->GetSemaphoreWin32HandleKHR(hwctx->
act_dev, &sem_export,
3522 &ext_sem_desc.handle.win32.handle);
3524 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &sem_export,
3525 &ext_sem_desc.handle.fd);
3527 if (
ret != VK_SUCCESS) {
3533 dst_int->ext_sem_handle[idx] = ext_sem_desc.handle.win32.handle;
3536 ret =
CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[idx],
3540 close(ext_sem_desc.handle.fd);
3568 CudaFunctions *cu = cu_internal->
cuda_dl;
3569 CUarray_format cufmt =
desc->comp[0].depth > 8 ? CU_AD_FORMAT_UNSIGNED_INT16 :
3570 CU_AD_FORMAT_UNSIGNED_INT8;
3575 if (!dst_int->cuda_fc_ref) {
3579 if (!dst_int->cuda_fc_ref)
3583 for (
int i = 0;
i < nb_images;
i++) {
3584 err = export_mem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
3589 err = export_sem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
3595 if (nb_images !=
planes) {
3597 VkImageSubresource subres = {
3598 .aspectMask =
i == 2 ? VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT :
3599 i == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3600 VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT
3602 VkSubresourceLayout
layout = { 0 };
3603 vk->GetImageSubresourceLayout(hwctx->
act_dev, dst_f->
img[
FFMIN(
i, nb_images - 1)],
3610 CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = {
3615 .NumChannels = 1 + ((
planes == 2) &&
i),
3623 tex_desc.arrayDesc.Width = p_w;
3624 tex_desc.arrayDesc.Height = p_h;
3626 ret =
CHECK_CU(cu->cuExternalMemoryGetMappedMipmappedArray(&dst_int->cu_mma[
i],
3627 dst_int->ext_mem[
FFMIN(
i, nb_images - 1)],
3634 ret =
CHECK_CU(cu->cuMipmappedArrayGetLevel(&dst_int->cu_array[
i],
3635 dst_int->cu_mma[
i], 0));
3666 CudaFunctions *cu = cu_internal->
cuda_dl;
3676 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
3680 err = vulkan_export_to_cuda(hwfc,
src->hw_frames_ctx,
dst);
3689 s_w_par[
i].params.fence.value = dst_f->
sem_value[
i] + 0;
3690 s_s_par[
i].params.fence.value = dst_f->
sem_value[
i] + 1;
3693 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
3694 planes, cuda_dev->stream));
3699 CUDA_MEMCPY2D cpy = {
3700 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
3701 .srcDevice = (CUdeviceptr)
src->data[
i],
3702 .srcPitch =
src->linesize[
i],
3705 .dstMemoryType = CU_MEMORYTYPE_ARRAY,
3706 .dstArray = dst_int->cu_array[
i],
3712 cpy.WidthInBytes = p_w *
desc->comp[
i].step;
3715 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
3720 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
3721 planes, cuda_dev->stream));
3747 switch (
src->format) {
3752 return vulkan_map_from_vaapi(hwfc,
dst,
src,
flags);
3758 return vulkan_map_from_drm(hwfc,
dst,
src,
flags);
3768 typedef struct VulkanDRMMapping {
3783 static inline uint32_t vulkan_fmt_to_drm(
VkFormat vkfmt)
3786 if (vulkan_drm_format_map[
i].vk_format == vkfmt)
3787 return vulkan_drm_format_map[
i].drm_fourcc;
3788 return DRM_FORMAT_INVALID;
3802 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
3803 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
3805 VkSemaphoreWaitInfo wait_info = {
3806 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
3808 .semaphoreCount =
planes,
3820 wait_info.pSemaphores =
f->sem;
3821 wait_info.pValues =
f->sem_value;
3823 vk->WaitSemaphores(hwctx->
act_dev, &wait_info, UINT64_MAX);
3829 ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->
act_dev,
f->img[0],
3831 if (
ret != VK_SUCCESS) {
3837 for (
int i = 0; (
i <
planes) && (
f->mem[
i]);
i++) {
3838 VkMemoryGetFdInfoKHR export_info = {
3839 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
3840 .memory =
f->mem[
i],
3841 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3844 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
3846 if (
ret != VK_SUCCESS) {
3859 VkSubresourceLayout
layout;
3860 VkImageSubresource sub = {
3861 .aspectMask = VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT,
3865 drm_desc->
layers[
i].
format = vulkan_fmt_to_drm(plane_vkfmt);
3876 if (
f->tiling == VK_IMAGE_TILING_OPTIMAL)
3879 vk->GetImageSubresourceLayout(hwctx->
act_dev,
f->img[
i], &sub, &
layout);
3885 dst->height =
src->height;
3886 dst->data[0] = (uint8_t *)drm_desc;
3930 switch (
dst->format) {
3940 return vulkan_map_to_vaapi(hwfc,
dst,
src,
flags);
3952 AVFrame *swf, VkBufferImageCopy *region,
3962 const VkMappedMemoryRange flush_info = {
3963 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
3964 .memory = vkbuf->
mem,
3965 .size = VK_WHOLE_SIZE,
3968 if (!upload && !(vkbuf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
3969 ret = vk->InvalidateMappedMemoryRanges(hwctx->
act_dev, 1,
3971 if (
ret != VK_SUCCESS) {
3981 region[
i].bufferRowLength,
3985 region[
i].imageExtent.height);
3990 vkbuf->mapped_mem + region[
i].bufferOffset,
3991 region[
i].bufferRowLength,
3993 region[
i].imageExtent.height);
3996 if (upload && !(vkbuf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
3997 ret = vk->FlushMappedMemoryRanges(hwctx->
act_dev, 1,
3999 if (
ret != VK_SUCCESS) {
4010 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4017 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4018 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4020 size_t buf_offset = 0;
4024 region[
i] = (VkBufferImageCopy) {
4025 .bufferOffset = buf_offset,
4027 p->
props.properties.limits.optimalBufferCopyRowPitchAlignment),
4028 .bufferImageHeight = p_h,
4029 .imageSubresource.layerCount = 1,
4030 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4034 buf_offset +=
FFALIGN(p_h*region[
i].bufferRowLength,
4035 p->
props.properties.limits.optimalBufferCopyOffsetAlignment);
4040 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
4041 VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
4049 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4056 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4057 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4066 while (swf->
buf[nb_src_bufs])
4070 if (nb_src_bufs == 1) {
4081 }
else if (nb_src_bufs ==
planes) {
4100 for (
int i = 0;
i < (*nb_bufs);
i++)
4114 int host_mapped = 0;
4129 VkCommandBuffer cmd_buf;
4146 region[
i] = (VkBufferImageCopy) {
4149 .bufferImageHeight = p_h,
4150 .imageSubresource.layerCount = 1,
4151 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4177 cmd_buf = exec->
buf;
4183 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
4184 VK_PIPELINE_STAGE_2_TRANSFER_BIT);
4208 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
4209 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,
4210 upload ? VK_ACCESS_TRANSFER_WRITE_BIT :
4211 VK_ACCESS_TRANSFER_READ_BIT,
4212 upload ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL :
4213 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4214 VK_QUEUE_FAMILY_IGNORED);
4216 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
4217 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
4218 .pImageMemoryBarriers = img_bar,
4219 .imageMemoryBarrierCount = nb_img_bar,
4223 int buf_idx =
FFMIN(
i, (nb_bufs - 1));
4224 int img_idx =
FFMIN(
i, (nb_images - 1));
4227 uint32_t orig_stride = region[
i].bufferRowLength;
4228 region[
i].bufferRowLength /=
desc->comp[
i].step;
4232 vk->CmdCopyBufferToImage(cmd_buf, vkbuf->
buf,
4233 hwf_vk->
img[img_idx],
4234 img_bar[img_idx].newLayout,
4237 vk->CmdCopyImageToBuffer(cmd_buf, hwf_vk->
img[img_idx],
4238 img_bar[img_idx].newLayout,
4242 region[
i].bufferRowLength = orig_stride;
4248 }
else if (!upload) {
4255 for (
int i = 0;
i < nb_bufs;
i++)
4266 switch (
src->format) {
4276 return vulkan_transfer_data_from_cuda(hwfc,
dst,
src);
4279 if (
src->hw_frames_ctx)
4303 CudaFunctions *cu = cu_internal->
cuda_dl;
4314 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
4318 err = vulkan_export_to_cuda(hwfc,
dst->hw_frames_ctx,
src);
4327 s_w_par[
i].params.fence.value = dst_f->
sem_value[
i] + 0;
4328 s_s_par[
i].params.fence.value = dst_f->
sem_value[
i] + 1;
4331 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
4332 nb_images, cuda_dev->stream));
4337 CUDA_MEMCPY2D cpy = {
4338 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
4339 .dstDevice = (CUdeviceptr)
dst->data[
i],
4340 .dstPitch =
dst->linesize[
i],
4343 .srcMemoryType = CU_MEMORYTYPE_ARRAY,
4344 .srcArray = dst_int->cu_array[
i],
4350 cpy.WidthInBytes =
w *
desc->comp[
i].step;
4353 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
4358 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
4359 nb_images, cuda_dev->stream));
4385 switch (
dst->format) {
4395 return vulkan_transfer_data_to_cuda(hwfc,
dst,
src);
4398 if (
dst->hw_frames_ctx)