21#define VK_NO_PROTOTYPES
22#define VK_ENABLE_BETA_EXTENSIONS
26#include <versionhelpers.h>
54#include <va/va_drmcommon.h>
57#include <sys/sysmacros.h>
61#include <drm_fourcc.h>
65#if HAVE_LINUX_DMA_BUF_H
67#include <linux/dma-buf.h>
73#define CHECK_CU(x) FF_CUDA_CHECK_DL(cuda_cu, cu, x)
87#ifdef VK_EXT_shader_long_vector
88 VkPhysicalDeviceShaderLongVectorFeaturesEXT long_vector;
91#ifdef VK_EXT_shader_replicated_composites
92 VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT replicated_composites;
95#ifdef VK_EXT_zero_initialize_device_memory
96 VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT zero_initialize;
99#ifdef VK_KHR_shader_expect_assume
100 VkPhysicalDeviceShaderExpectAssumeFeaturesKHR expect_assume;
103#ifdef VK_KHR_shader_maximal_reconvergence
104 VkPhysicalDeviceShaderMaximalReconvergenceFeaturesKHR maximal_reconvergence;
107#ifdef VK_KHR_maintenance9
108 VkPhysicalDeviceMaintenance9FeaturesKHR maintenance_9;
110#ifdef VK_KHR_maintenance11
111 VkPhysicalDeviceMaintenance11FeaturesKHR maintenance_11;
113#ifdef VK_KHR_unified_image_layouts
114 VkPhysicalDeviceUnifiedImageLayoutsFeaturesKHR unified_layouts;
118#ifdef VK_KHR_video_maintenance2
119 VkPhysicalDeviceVideoMaintenance2FeaturesKHR video_maintenance_2;
121#ifdef VK_KHR_video_decode_vp9
122 VkPhysicalDeviceVideoDecodeVP9FeaturesKHR vp9_decode;
124#ifdef VK_KHR_video_encode_av1
125 VkPhysicalDeviceVideoEncodeAV1FeaturesKHR av1_encode;
132#ifdef VK_KHR_shader_relaxed_extended_instruction
133 VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR relaxed_extended_instruction;
136#ifdef VK_KHR_internally_synchronized_queues
137 VkPhysicalDeviceInternallySynchronizedQueuesFeaturesKHR internal_queue_sync;
158 VkPhysicalDeviceExternalMemoryHostPropertiesEXT
hprops;
249 feats->
device = (VkPhysicalDeviceFeatures2) {
250 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
254 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES);
256 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES);
258 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES);
261 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES);
263 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES_KHR);
265 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT);
267#ifdef VK_EXT_shader_long_vector
269 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_LONG_VECTOR_FEATURES_EXT);
272#ifdef VK_EXT_shader_replicated_composites
274 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_REPLICATED_COMPOSITES_FEATURES_EXT);
277#ifdef VK_EXT_zero_initialize_device_memory
279 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_DEVICE_MEMORY_FEATURES_EXT);
282#ifdef VK_KHR_shader_expect_assume
284 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES_KHR);
287#ifdef VK_KHR_shader_maximal_reconvergence
289 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MAXIMAL_RECONVERGENCE_FEATURES_KHR);
292#ifdef VK_KHR_maintenance9
294 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_9_FEATURES_KHR);
296#ifdef VK_KHR_maintenance11
298 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_11_FEATURES_KHR);
300#ifdef VK_KHR_unified_image_layouts
302 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFIED_IMAGE_LAYOUTS_FEATURES_KHR);
306 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR);
307#ifdef VK_KHR_video_maintenance2
309 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR);
311#ifdef VK_KHR_video_decode_vp9
313 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR);
315#ifdef VK_KHR_video_encode_av1
317 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR);
321 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);
323 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR);
325 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT);
327 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR);
329#ifdef VK_KHR_shader_relaxed_extended_instruction
331 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR);
334#ifdef VK_KHR_internally_synchronized_queues
336 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INTERNALLY_SYNCHRONIZED_QUEUES_FEATURES_KHR);
340 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV);
346#define COPY_VAL(VAL) \
348 dst->VAL = src->VAL; \
351 COPY_VAL(device.features.shaderImageGatherExtended);
352 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
353 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
354 COPY_VAL(device.features.fragmentStoresAndAtomics);
355 COPY_VAL(device.features.vertexPipelineStoresAndAtomics);
356 COPY_VAL(device.features.shaderInt64);
357 COPY_VAL(device.features.shaderInt16);
358 COPY_VAL(device.features.shaderFloat64);
359 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
360 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
362 COPY_VAL(vulkan_1_1.samplerYcbcrConversion);
363 COPY_VAL(vulkan_1_1.storagePushConstant16);
364 COPY_VAL(vulkan_1_1.storageBuffer16BitAccess);
365 COPY_VAL(vulkan_1_1.uniformAndStorageBuffer16BitAccess);
367 COPY_VAL(vulkan_1_2.timelineSemaphore);
368 COPY_VAL(vulkan_1_2.scalarBlockLayout);
369 COPY_VAL(vulkan_1_2.bufferDeviceAddress);
370 COPY_VAL(vulkan_1_2.hostQueryReset);
371 COPY_VAL(vulkan_1_2.storagePushConstant8);
373 COPY_VAL(vulkan_1_2.storageBuffer8BitAccess);
374 COPY_VAL(vulkan_1_2.uniformAndStorageBuffer8BitAccess);
376 COPY_VAL(vulkan_1_2.shaderBufferInt64Atomics);
377 COPY_VAL(vulkan_1_2.shaderSharedInt64Atomics);
378 COPY_VAL(vulkan_1_2.vulkanMemoryModel);
379 COPY_VAL(vulkan_1_2.vulkanMemoryModelDeviceScope);
380 COPY_VAL(vulkan_1_2.vulkanMemoryModelAvailabilityVisibilityChains);
381 COPY_VAL(vulkan_1_2.uniformBufferStandardLayout);
382 COPY_VAL(vulkan_1_2.runtimeDescriptorArray);
383 COPY_VAL(vulkan_1_2.shaderSubgroupExtendedTypes);
384 COPY_VAL(vulkan_1_2.shaderUniformBufferArrayNonUniformIndexing);
385 COPY_VAL(vulkan_1_2.shaderSampledImageArrayNonUniformIndexing);
386 COPY_VAL(vulkan_1_2.shaderStorageBufferArrayNonUniformIndexing);
387 COPY_VAL(vulkan_1_2.shaderStorageImageArrayNonUniformIndexing);
389 COPY_VAL(vulkan_1_3.dynamicRendering);
391 COPY_VAL(vulkan_1_3.synchronization2);
392 COPY_VAL(vulkan_1_3.computeFullSubgroups);
393 COPY_VAL(vulkan_1_3.subgroupSizeControl);
394 COPY_VAL(vulkan_1_3.shaderZeroInitializeWorkgroupMemory);
395 COPY_VAL(vulkan_1_3.dynamicRendering);
397 COPY_VAL(timeline_semaphore.timelineSemaphore);
398 COPY_VAL(subgroup_rotate.shaderSubgroupRotate);
399 COPY_VAL(host_image_copy.hostImageCopy);
401#ifdef VK_EXT_shader_long_vector
405#ifdef VK_EXT_shader_replicated_composites
406 COPY_VAL(replicated_composites.shaderReplicatedComposites);
409#ifdef VK_EXT_zero_initialize_device_memory
410 COPY_VAL(zero_initialize.zeroInitializeDeviceMemory);
413 COPY_VAL(video_maintenance_1.videoMaintenance1);
414#ifdef VK_KHR_video_maintenance2
415 COPY_VAL(video_maintenance_2.videoMaintenance2);
418#ifdef VK_KHR_video_decode_vp9
419 COPY_VAL(vp9_decode.videoDecodeVP9);
422#ifdef VK_KHR_video_encode_av1
423 COPY_VAL(av1_encode.videoEncodeAV1);
426 COPY_VAL(shader_object.shaderObject);
428 COPY_VAL(cooperative_matrix.cooperativeMatrix);
430 COPY_VAL(atomic_float.shaderBufferFloat32Atomics);
431 COPY_VAL(atomic_float.shaderBufferFloat32AtomicAdd);
433 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayout);
434 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayoutScalarBlockLayout);
435 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayout8BitAccess);
436 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayout16BitAccess);
438#ifdef VK_KHR_shader_relaxed_extended_instruction
439 COPY_VAL(relaxed_extended_instruction.shaderRelaxedExtendedInstruction);
442#ifdef VK_KHR_shader_expect_assume
443 COPY_VAL(expect_assume.shaderExpectAssume);
446#ifdef VK_KHR_shader_maximal_reconvergence
447 COPY_VAL(maximal_reconvergence.shaderMaximalReconvergence);
450#ifdef VK_KHR_maintenance9
451 COPY_VAL(maintenance_9.maintenance9);
453#ifdef VK_KHR_maintenance11
454 COPY_VAL(maintenance_11.maintenance11);
456#ifdef VK_KHR_unified_image_layouts
457 COPY_VAL(unified_layouts.unifiedImageLayouts);
458 COPY_VAL(unified_layouts.unifiedImageLayoutsVideo);
461#ifdef VK_KHR_internally_synchronized_queues
462 COPY_VAL(internal_queue_sync.internallySynchronizedQueues);
470#define ASPECT_2PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT)
471#define ASPECT_3PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)
483 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_GRAY8, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8_UNORM } },
484 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
485 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY12, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
486 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY14, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
487 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
488 { VK_FORMAT_R32_UINT,
AV_PIX_FMT_GRAY32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_UINT } },
489 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GRAYF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_SFLOAT } },
492 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_BGRA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
493 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGBA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
494 { VK_FORMAT_R8G8B8_UNORM,
AV_PIX_FMT_RGB24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8_UNORM } },
495 { VK_FORMAT_B8G8R8_UNORM,
AV_PIX_FMT_BGR24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8_UNORM } },
496 { VK_FORMAT_R16G16B16_UNORM,
AV_PIX_FMT_RGB48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16_UNORM } },
497 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_RGBA64, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
498 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_BGR0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
499 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGB0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
500 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_X2RGB10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
501 { VK_FORMAT_A2B10G10R10_UNORM_PACK32,
AV_PIX_FMT_X2BGR10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2B10G10R10_UNORM_PACK32 } },
502 { VK_FORMAT_R32G32B32_SFLOAT,
AV_PIX_FMT_RGBF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_SFLOAT } },
503 { VK_FORMAT_R16G16B16A16_SFLOAT,
AV_PIX_FMT_RGBAF16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_SFLOAT } },
504 { VK_FORMAT_R32G32B32A32_SFLOAT,
AV_PIX_FMT_RGBAF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_SFLOAT } },
505 { VK_FORMAT_R32G32B32_UINT,
AV_PIX_FMT_RGB96, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_UINT } },
506 { VK_FORMAT_R32G32B32A32_UINT,
AV_PIX_FMT_RGBA128, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_UINT } },
509 { 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 } },
510 { 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 } },
511 { 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 } },
512 { 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 } },
513 { 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 } },
514 { VK_FORMAT_R16_SFLOAT,
AV_PIX_FMT_GBRPF16, VK_IMAGE_ASPECT_COLOR_BIT, 3, 3, 3, { VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16_SFLOAT } },
515 { 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 } },
518 { 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 } },
519 { 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 } },
520 { 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 } },
521 { 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 } },
522 { 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 } },
523 { VK_FORMAT_R16_SFLOAT,
AV_PIX_FMT_GBRAPF16, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16_SFLOAT } },
524 { 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 } },
525 { 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 } },
532 { 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 } },
533 { 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 } },
538 { 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 } },
539 { 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 } },
544 { 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 } },
545 { 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 } },
563 { VK_FORMAT_G8B8G8R8_422_UNORM,
AV_PIX_FMT_YUYV422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
564 { VK_FORMAT_B8G8R8G8_422_UNORM,
AV_PIX_FMT_UYVY422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
565 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
AV_PIX_FMT_Y210, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
566 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
AV_PIX_FMT_Y212, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
567 { VK_FORMAT_G16B16G16R16_422_UNORM,
AV_PIX_FMT_Y216, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
570 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_YUVA420P, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } },
571 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_YUVA420P10, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
572 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_YUVA420P16, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
575 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_YUVA422P, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } },
576 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_YUVA422P10, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
577 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_YUVA422P12, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
578 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_YUVA422P16, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
581 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_YUVA444P, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } },
582 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_YUVA444P10, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
583 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_YUVA444P12, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
584 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_YUVA444P16, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
587 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_XV30, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
588 { VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
AV_PIX_FMT_XV36, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
589 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_XV48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
610 VkImageTiling tiling,
613 VkImageAspectFlags *
aspect,
614 VkImageUsageFlags *supported_usage,
615 int disable_multiplane,
int need_storage)
621 const VkFormatFeatureFlagBits2 basic_flags = VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
622 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
623 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
627 VkFormatProperties3 fprops = {
628 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3,
630 VkFormatProperties2 prop = {
631 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
634 VkFormatFeatureFlagBits2 feats_primary, feats_secondary;
635 int basics_primary = 0, basics_secondary = 0;
636 int storage_primary = 0, storage_secondary = 0;
638 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
642 feats_primary = tiling == VK_IMAGE_TILING_LINEAR ?
643 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
644 basics_primary = (feats_primary & basic_flags) == basic_flags;
645 storage_primary = !!(feats_primary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
648 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
651 feats_secondary = tiling == VK_IMAGE_TILING_LINEAR ?
652 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
653 basics_secondary = (feats_secondary & basic_flags) == basic_flags;
654 storage_secondary = !!(feats_secondary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
656 feats_secondary = feats_primary;
657 basics_secondary = basics_primary;
658 storage_secondary = storage_primary;
661 if (basics_primary &&
663 (!need_storage || (need_storage && (storage_primary | storage_secondary)))) {
678 ((need_storage && (storage_primary | storage_secondary)) ?
679 VK_IMAGE_USAGE_STORAGE_BIT : 0);
681 }
else if (basics_secondary &&
682 (!need_storage || (need_storage && storage_secondary))) {
703#if CONFIG_VULKAN_STATIC
704VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance,
713#if CONFIG_VULKAN_STATIC
716 static const char *lib_names[] = {
719#elif defined(__APPLE__)
730 p->libvulkan = dlopen(lib_names[
i], RTLD_NOW | RTLD_LOCAL);
740 hwctx->
get_proc_addr = (PFN_vkGetInstanceProcAddr)dlsym(p->libvulkan,
"vkGetInstanceProcAddr");
769#ifdef VK_KHR_shader_relaxed_extended_instruction
772#ifdef VK_EXT_shader_long_vector
775#ifdef VK_EXT_shader_replicated_composites
778#ifdef VK_EXT_zero_initialize_device_memory
781#ifdef VK_KHR_shader_expect_assume
784#ifdef VK_KHR_shader_maximal_reconvergence
787#ifdef VK_KHR_maintenance9
790#ifdef VK_KHR_maintenance11
793#ifdef VK_KHR_unified_image_layouts
797#ifdef VK_KHR_video_maintenance2
800#ifdef VK_KHR_internally_synchronized_queues
824#ifdef VK_KHR_video_decode_vp9
827#ifdef VK_KHR_video_encode_av1
863 VkDebugUtilsMessageTypeFlagsEXT messageType,
864 const VkDebugUtilsMessengerCallbackDataEXT *
data,
871 switch (
data->messageIdNumber) {
880 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: l =
AV_LOG_VERBOSE;
break;
881 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: l =
AV_LOG_INFO;
break;
882 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: l =
AV_LOG_WARNING;
break;
883 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: l =
AV_LOG_ERROR;
break;
888 for (
int i = 0;
i <
data->cmdBufLabelCount;
i++)
894#define ADD_VAL_TO_LIST(list, count, val) \
896 list = av_realloc_array(list, ++count, sizeof(*list)); \
898 err = AVERROR(ENOMEM); \
901 list[count - 1] = av_strdup(val); \
902 if (!list[count - 1]) { \
903 err = AVERROR(ENOMEM); \
908#define RELEASE_PROPS(props, count) \
910 for (int i = 0; i < count; i++) \
911 av_free((void *)((props)[i])); \
912 av_free((void *)props); \
918 VkDeviceSize max_vram = 0, max_visible_vram = 0;
922 for (
int i = 0;
i < p->mprops.memoryTypeCount;
i++) {
923 const VkMemoryType
type = p->mprops.memoryTypes[
i];
924 const VkMemoryHeap heap = p->mprops.memoryHeaps[
type.heapIndex];
925 if (!(
type.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
927 max_vram =
FFMAX(max_vram, heap.size);
928 if (
type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
929 max_visible_vram =
FFMAX(max_visible_vram, heap.size);
932 return max_vram - max_visible_vram < 1024;
948 const char *
const **
dst, uint32_t *
num,
952 const char **extension_names =
NULL;
956 int err = 0, found, extensions_found = 0;
959 int optional_exts_num;
960 uint32_t sup_ext_count;
961 char *user_exts_str =
NULL;
963 VkExtensionProperties *sup_ext;
973 if (!user_exts_str) {
978 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count,
NULL);
979 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
982 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count, sup_ext);
990 if (!user_exts_str) {
995 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
996 &sup_ext_count,
NULL);
997 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
1000 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
1001 &sup_ext_count, sup_ext);
1004 for (
int i = 0;
i < optional_exts_num;
i++) {
1005 tstr = optional_exts[
i].
name;
1009 if (!strcmp(tstr, VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME) &&
1017 (!strcmp(tstr, VK_EXT_SHADER_OBJECT_EXTENSION_NAME))) {
1021 for (
int j = 0; j < sup_ext_count; j++) {
1022 if (!strcmp(tstr, sup_ext[j].extensionName)) {
1031 p->vkctx.extensions |= optional_exts[
i].
flag;
1039 tstr = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
1041 for (
int j = 0; j < sup_ext_count; j++) {
1042 if (!strcmp(tstr, sup_ext[j].extensionName)) {
1058#ifdef VK_KHR_shader_relaxed_extended_instruction
1060 tstr = VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME;
1062 for (
int j = 0; j < sup_ext_count; j++) {
1063 if (!strcmp(tstr, sup_ext[j].extensionName)) {
1077 if (user_exts_str) {
1078 char *save, *token =
av_strtok(user_exts_str,
"+", &save);
1081 for (
int j = 0; j < sup_ext_count; j++) {
1082 if (!strcmp(token, sup_ext[j].extensionName)) {
1098 *
dst = extension_names;
1099 *
num = extensions_found;
1113 const char *
const **
dst, uint32_t *
num,
1120 static const char layer_standard_validation[] = {
"VK_LAYER_KHRONOS_validation" };
1121 int layer_standard_validation_found = 0;
1123 uint32_t sup_layer_count;
1124 VkLayerProperties *sup_layers;
1127 char *user_layers_str =
NULL;
1130 const char **enabled_layers =
NULL;
1131 uint32_t enabled_layers_count = 0;
1139 vk->EnumerateInstanceLayerProperties(&sup_layer_count,
NULL);
1140 sup_layers =
av_malloc_array(sup_layer_count,
sizeof(VkLayerProperties));
1143 vk->EnumerateInstanceLayerProperties(&sup_layer_count, sup_layers);
1146 for (
int i = 0;
i < sup_layer_count;
i++)
1150 if (!debug_opt && !user_layers)
1155 if (!strcmp(debug_opt->
value,
"printf")) {
1157 }
else if (!strcmp(debug_opt->
value,
"validate")) {
1159 }
else if (!strcmp(debug_opt->
value,
"practices")) {
1162 char *end_ptr =
NULL;
1163 int idx = strtol(debug_opt->
value, &end_ptr, 10);
1164 if (end_ptr == debug_opt->
value || end_ptr[0] !=
'\0' ||
1179 for (
int i = 0;
i < sup_layer_count;
i++) {
1180 if (!strcmp(layer_standard_validation, sup_layers[
i].layerName)) {
1182 layer_standard_validation);
1183 ADD_VAL_TO_LIST(enabled_layers, enabled_layers_count, layer_standard_validation);
1185 layer_standard_validation_found = 1;
1189 if (!layer_standard_validation_found) {
1191 "Validation Layer \"%s\" not supported\n", layer_standard_validation);
1202 if (!user_layers_str) {
1207 token =
av_strtok(user_layers_str,
"+", &save);
1212 if (!strcmp(layer_standard_validation, token) && layer_standard_validation_found) {
1218 for (
int j = 0; j < sup_layer_count; j++) {
1219 if (!strcmp(token, sup_layers[j].layerName)) {
1230 if (!strcmp(layer_standard_validation, token))
1234 "Layer \"%s\" not supported\n", token);
1251 *
dst = enabled_layers;
1252 *
num = enabled_layers_count;
1267 VkApplicationInfo application_info = {
1268 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
1269 .pApplicationName =
"ffmpeg",
1273 .pEngineName =
"libavutil",
1274 .apiVersion = VK_API_VERSION_1_3,
1279 VkValidationFeaturesEXT validation_features = {
1280 .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
1282 VkInstanceCreateInfo inst_props = {
1283 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
1284 .pApplicationInfo = &application_info,
1300 &inst_props.enabledLayerCount, debug_mode);
1306 &inst_props.enabledExtensionCount, *debug_mode);
1314 static const VkValidationFeatureEnableEXT feat_list_validate[] = {
1315 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1316 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1317 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
1319 validation_features.pEnabledValidationFeatures = feat_list_validate;
1320 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_validate);
1321 inst_props.pNext = &validation_features;
1323 static const VkValidationFeatureEnableEXT feat_list_debug[] = {
1324 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1325 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1326 VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT,
1328 validation_features.pEnabledValidationFeatures = feat_list_debug;
1329 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_debug);
1330 inst_props.pNext = &validation_features;
1332 static const VkValidationFeatureEnableEXT feat_list_practices[] = {
1333 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1334 VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT,
1336 validation_features.pEnabledValidationFeatures = feat_list_practices;
1337 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_practices);
1338 inst_props.pNext = &validation_features;
1342 for (
int i = 0;
i < inst_props.enabledExtensionCount;
i++) {
1343 if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
1344 inst_props.ppEnabledExtensionNames[
i])) {
1345 inst_props.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
1352 ret = vk->CreateInstance(&inst_props, hwctx->
alloc, &hwctx->
inst);
1355 if (ret != VK_SUCCESS) {
1372 VkDebugUtilsMessengerCreateInfoEXT dbg = {
1373 .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
1374 .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
1375 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
1376 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
1377 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
1378 .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
1379 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
1380 VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
1385 vk->CreateDebugUtilsMessengerEXT(hwctx->
inst, &dbg,
1386 hwctx->
alloc, &p->debug_ctx);
1392 RELEASE_PROPS(inst_props.ppEnabledLayerNames, inst_props.enabledLayerCount);
1411 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
return "integrated";
1412 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
return "discrete";
1413 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
return "virtual";
1414 case VK_PHYSICAL_DEVICE_TYPE_CPU:
return "software";
1415 default:
return "unknown";
1422 int err = 0, choice = -1;
1428 VkPhysicalDevice *devices =
NULL;
1429 VkPhysicalDeviceIDProperties *idp =
NULL;
1430 VkPhysicalDeviceProperties2 *prop =
NULL;
1431 VkPhysicalDeviceDriverProperties *driver_prop =
NULL;
1432 VkPhysicalDeviceDrmPropertiesEXT *drm_prop =
NULL;
1434 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &
num,
NULL);
1435 if (ret != VK_SUCCESS || !
num) {
1444 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &
num, devices);
1445 if (ret != VK_SUCCESS) {
1479 for (
int i = 0;
i <
num;
i++) {
1481 drm_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT;
1482 driver_prop[
i].pNext = &drm_prop[
i];
1484 driver_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
1485 idp[
i].pNext = &driver_prop[
i];
1486 idp[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
1487 prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1488 prop[
i].pNext = &idp[
i];
1490 vk->GetPhysicalDeviceProperties2(devices[
i], &prop[
i]);
1492 prop[
i].properties.deviceName,
1494 prop[
i].properties.deviceID);
1498 for (
int i = 0;
i <
num;
i++) {
1499 if (!memcmp(idp[
i].deviceUUID, select->
uuid, VK_UUID_SIZE)) {
1508 for (
int i = 0;
i <
num;
i++) {
1509 if ((select->
drm_major == drm_prop[
i].primaryMajor &&
1510 select->
drm_minor == drm_prop[
i].primaryMinor) ||
1511 (select->
drm_major == drm_prop[
i].renderMajor &&
1512 select->
drm_minor == drm_prop[
i].renderMinor)) {
1521 }
else if (select->
name) {
1523 for (
int i = 0;
i <
num;
i++) {
1524 if (strstr(prop[
i].properties.deviceName, select->
name)) {
1535 for (
int i = 0;
i <
num;
i++) {
1536 if (select->
pci_device == prop[
i].properties.deviceID) {
1547 for (
int i = 0;
i <
num;
i++) {
1548 if (select->
vendor_id == prop[
i].properties.vendorID) {
1559 choice = select->
index;
1571 choice, prop[choice].properties.deviceName,
1573 prop[choice].properties.deviceID);
1575 p->props = prop[choice];
1576 p->props.pNext =
NULL;
1577 p->dprops = driver_prop[choice];
1578 p->dprops.pNext =
NULL;
1592 VkQueueFlagBits
flags)
1595 uint32_t min_score = UINT32_MAX;
1597 for (
int i = 0;
i < num_qf;
i++) {
1598 VkQueueFlagBits qflags = qf[
i].queueFamilyProperties.queueFlags;
1601 if ((
flags & VK_QUEUE_TRANSFER_BIT) &&
1602 (qflags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)))
1603 qflags |= VK_QUEUE_TRANSFER_BIT;
1605 if (qflags &
flags) {
1606 uint32_t score =
av_popcount(qflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1607 if (score < min_score) {
1615 qf[
index].queueFamilyProperties.timestampValidBits++;
1621 VkQueueFamilyVideoPropertiesKHR *qf_vid, uint32_t num_qf,
1622 VkVideoCodecOperationFlagsKHR
flags)
1625 uint32_t min_score = UINT32_MAX;
1627 for (
int i = 0;
i < num_qf;
i++) {
1628 const VkQueueFlags qflags = qf[
i].queueFamilyProperties.queueFlags;
1629 const VkVideoCodecOperationFlagsKHR vflags = qf_vid[
i].videoCodecOperations;
1631 if (!(qflags & (VK_QUEUE_VIDEO_ENCODE_BIT_KHR | VK_QUEUE_VIDEO_DECODE_BIT_KHR)))
1634 if (vflags &
flags) {
1635 uint32_t score =
av_popcount(vflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1636 if (score < min_score) {
1644 qf[
index].queueFamilyProperties.timestampValidBits++;
1656 VkQueueFamilyProperties2 *qf =
NULL;
1657 VkQueueFamilyVideoPropertiesKHR *qf_vid =
NULL;
1660 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &
num,
NULL);
1675 for (uint32_t
i = 0;
i <
num;
i++) {
1676 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1677 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1679 qf[
i] = (VkQueueFamilyProperties2) {
1680 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
1686 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &
num, qf);
1689 for (
int i = 0;
i <
num;
i++) {
1691 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_GRAPHICS_BIT) ?
" graphics" :
"",
1692 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_COMPUTE_BIT) ?
" compute" :
"",
1693 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_TRANSFER_BIT) ?
" transfer" :
"",
1694 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ?
" encode" :
"",
1695 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_DECODE_BIT_KHR) ?
" decode" :
"",
1696 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_SPARSE_BINDING_BIT) ?
" sparse" :
"",
1697 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_OPTICAL_FLOW_BIT_NV) ?
" optical_flow" :
"",
1698 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_PROTECTED_BIT) ?
" protected" :
"",
1699 qf[
i].queueFamilyProperties.queueCount);
1703 qf[
i].queueFamilyProperties.timestampValidBits = 0;
1708#ifdef VK_KHR_internally_synchronized_queues
1710 hwctx->
queue_flags |= VK_DEVICE_QUEUE_CREATE_INTERNALLY_SYNCHRONIZED_BIT_KHR;
1714#define PICK_QF(type, vid_op) \
1720 idx = pick_video_queue_family(qf, qf_vid, num, vid_op); \
1722 idx = pick_queue_family(qf, num, type); \
1727 for (i = 0; i < hwctx->nb_qf; i++) { \
1728 if (hwctx->qf[i].idx == idx) { \
1729 hwctx->qf[i].flags |= type; \
1730 hwctx->qf[i].video_caps |= vid_op; \
1734 if (i == hwctx->nb_qf) { \
1735 hwctx->qf[i].idx = idx; \
1736 hwctx->qf[i].num = qf[idx].queueFamilyProperties.queueCount; \
1737 if (p->limit_queues || \
1738 p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) { \
1739 int max = p->limit_queues; \
1740 if (type == VK_QUEUE_GRAPHICS_BIT) \
1741 hwctx->qf[i].num = FFMIN(hwctx->qf[i].num, \
1744 hwctx->qf[i].num = FFMIN(hwctx->qf[i].num, max); \
1746 hwctx->qf[i].flags = type; \
1747 hwctx->qf[i].video_caps = vid_op; \
1752 PICK_QF(VK_QUEUE_GRAPHICS_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1753 PICK_QF(VK_QUEUE_COMPUTE_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1754 PICK_QF(VK_QUEUE_TRANSFER_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1756 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR);
1757 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR);
1759 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR);
1760 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR);
1762#ifdef VK_KHR_video_decode_vp9
1763 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR);
1766#ifdef VK_KHR_video_encode_av1
1767 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR);
1769 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR);
1772 PICK_QF(VK_QUEUE_OPTICAL_FLOW_BIT_NV, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1780 sizeof(VkDeviceQueueCreateInfo));
1781 if (!cd->pQueueCreateInfos)
1784 for (uint32_t
i = 0;
i < hwctx->
nb_qf;
i++) {
1787 VkDeviceQueueCreateInfo *pc;
1788 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++) {
1789 if (hwctx->
qf[
i].
idx == cd->pQueueCreateInfos[j].queueFamilyIndex) {
1799 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++)
1800 av_free((
void *)cd->pQueueCreateInfos[
i].pQueuePriorities);
1801 av_free((
void *)cd->pQueueCreateInfos);
1805 for (uint32_t j = 0; j < hwctx->
qf[
i].
num; j++)
1808 pc = (VkDeviceQueueCreateInfo *)cd->pQueueCreateInfos;
1809 pc[cd->queueCreateInfoCount++] = (VkDeviceQueueCreateInfo) {
1810 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1812 .queueFamilyIndex = hwctx->
qf[
i].
idx,
1813 .queueCount = hwctx->
qf[
i].
num,
1836 vk->DestroyDebugUtilsMessengerEXT(hwctx->
inst, p->debug_ctx,
1840 vk->DestroyInstance(hwctx->
inst, hwctx->
alloc);
1843 dlclose(p->libvulkan);
1854 for (uint32_t
i = 0;
i < p->nb_tot_qfs;
i++) {
1866 int disable_multiplane,
1877 VkDeviceCreateInfo dev_info = {
1878 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1890 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->mprops);
1894 &dev_info.enabledExtensionCount, debug_mode))) {
1895 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1896 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1897 av_free((
void *)dev_info.pQueueCreateInfos);
1903 vk->GetPhysicalDeviceFeatures2(hwctx->
phys_dev, &supported_feats.
device);
1908 dev_info.pNext = p->feats.device.pNext;
1909 dev_info.pEnabledFeatures = &p->feats.device.features;
1914 p->limit_queues = strtol(opt_d->
value,
NULL, 10);
1921 ret = vk->CreateDevice(hwctx->
phys_dev, &dev_info, hwctx->
alloc,
1924 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1925 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1926 av_free((
void *)dev_info.pQueueCreateInfos);
1928 if (ret != VK_SUCCESS) {
1931 for (
int i = 0;
i < dev_info.enabledExtensionCount;
i++)
1932 av_free((
void *)dev_info.ppEnabledExtensionNames[
i]);
1933 av_free((
void *)dev_info.ppEnabledExtensionNames);
1941 p->use_linear_images = strtol(opt_d->
value,
NULL, 10);
1944 p->disable_multiplane = disable_multiplane;
1945 if (!p->disable_multiplane) {
1948 p->disable_multiplane = strtol(opt_d->
value,
NULL, 10);
1952 p->avoid_host_import = p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY;
1955 p->avoid_host_import = strtol(opt_d->
value,
NULL, 10);
1992 VkQueueFamilyProperties2 *qf;
1993 VkQueueFamilyVideoPropertiesKHR *qf_vid;
1994 VkPhysicalDeviceExternalSemaphoreInfo ext_sem_props_info;
2013 p->props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
2014 p->props.pNext = &p->hprops;
2015 p->hprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;
2016 p->hprops.pNext = &p->dprops;
2017 p->dprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
2019 vk->GetPhysicalDeviceProperties2(hwctx->
phys_dev, &p->props);
2021 p->props.properties.deviceName);
2024 p->props.properties.limits.optimalBufferCopyRowPitchAlignment);
2026 p->props.properties.limits.minMemoryMapAlignment);
2028 p->props.properties.limits.nonCoherentAtomSize);
2031 p->hprops.minImportedHostPointerAlignment);
2033 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &qf_num,
NULL);
2039 ext_sem_props_info = (VkPhysicalDeviceExternalSemaphoreInfo) {
2040 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
2044 ext_sem_props_info.handleType =
2046 IsWindows8OrGreater()
2047 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2048 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
2050 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
2052 p->ext_sem_props_opaque.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES;
2053 vk->GetPhysicalDeviceExternalSemaphoreProperties(hwctx->
phys_dev,
2054 &ext_sem_props_info,
2055 &p->ext_sem_props_opaque);
2061 qf_vid =
av_malloc_array(qf_num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
2067 for (uint32_t
i = 0;
i < qf_num;
i++) {
2068 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
2069 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
2071 qf[
i] = (VkQueueFamilyProperties2) {
2072 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
2077 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &qf_num, qf);
2079 p->nb_tot_qfs = qf_num;
2082 p->qf_mutex =
av_calloc(qf_num,
sizeof(*p->qf_mutex));
2088 for (uint32_t
i = 0;
i < qf_num;
i++) {
2089 p->qf_mutex[
i] =
av_calloc(qf[
i].queueFamilyProperties.queueCount,
2090 sizeof(**p->qf_mutex));
2091 if (!p->qf_mutex[
i]) {
2095 for (uint32_t j = 0; j < qf[
i].queueFamilyProperties.queueCount; j++) {
2107 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
2109 hwctx->
qf[
i].
flags & (VK_QUEUE_VIDEO_DECODE_BIT_KHR |
2110 VK_QUEUE_VIDEO_ENCODE_BIT_KHR)) {
2117 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
2121 for (
int j = (
i - 1); j >= 0; j--) {
2128 p->img_qfs[p->nb_img_qfs++] = hwctx->
qf[
i].
idx;
2131#if FF_API_VULKAN_SYNC_QUEUES
2133 if (!hwctx->lock_queue)
2135 if (!hwctx->unlock_queue)
2141 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->mprops);
2143 p->vkctx.device =
ctx;
2144 p->vkctx.hwctx = hwctx;
2147 p->compute_qf =
ff_vk_qf_find(&p->vkctx, VK_QUEUE_COMPUTE_BIT, 0);
2148 p->transfer_qf =
ff_vk_qf_find(&p->vkctx, VK_QUEUE_TRANSFER_BIT, 0);
2151 p->transfer_offset_align = 1;
2152 if (p->transfer_qf) {
2153 VkQueueFlags
flags = p->vkctx.qf_props[p->transfer_qf->idx].queueFamilyProperties.queueFlags;
2154 if (!(
flags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)))
2155 p->transfer_offset_align = 4;
2157#ifdef VK_KHR_maintenance11
2158 if (p->vkctx.maintenance_11_feats.maintenance11)
2159 p->transfer_offset_align = 1;
2163 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->mprops);
2175 if (device && device[0]) {
2181 dev_select.
index = strtol(device, &end, 10);
2182 if (end == device || *end) {
2183 dev_select.
index = 0;
2184 dev_select.
name = device;
2201 switch(src_ctx->
type) {
2205 VADisplay dpy = src_hwctx->
display;
2206#if VA_CHECK_VERSION(1, 15, 0)
2208 VADisplayAttribute attr = {
2209 .type = VADisplayPCIID,
2214#if VA_CHECK_VERSION(1, 15, 0)
2215 vas = vaGetDisplayAttributes(dpy, &attr, 1);
2216 if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED)
2217 dev_select.pci_device = (attr.value & 0xFFFF);
2220 if (!dev_select.pci_device) {
2221 vendor = vaQueryVendorString(dpy);
2227 if (strstr(vendor,
"AMD"))
2228 dev_select.vendor_id = 0x1002;
2237 struct stat drm_node_info;
2238 drmDevice *drm_dev_info;
2241 err = fstat(src_hwctx->
fd, &drm_node_info);
2248 dev_select.drm_major = major(drm_node_info.st_dev);
2249 dev_select.drm_minor = minor(drm_node_info.st_dev);
2250 dev_select.has_drm = 1;
2252 err = drmGetDevice(src_hwctx->
fd, &drm_dev_info);
2259 if (drm_dev_info->bustype == DRM_BUS_PCI)
2260 dev_select.pci_device = drm_dev_info->deviceinfo.pci->device_id;
2262 drmFreeDevice(&drm_dev_info);
2272 CudaFunctions *cu = cu_internal->
cuda_dl;
2274 int ret =
CHECK_CU(cu->cuDeviceGetUuid((CUuuid *)&dev_select.uuid,
2281 dev_select.has_uuid = 1;
2296 const void *hwconfig,
2304 p->use_linear_images ? VK_IMAGE_TILING_LINEAR :
2305 VK_IMAGE_TILING_OPTIMAL,
2317 p->use_linear_images ? VK_IMAGE_TILING_LINEAR :
2318 VK_IMAGE_TILING_OPTIMAL,
2332 constraints->
max_width = p->props.properties.limits.maxImageDimension2D;
2333 constraints->
max_height = p->props.properties.limits.maxImageDimension2D;
2346 VkMemoryPropertyFlagBits req_flags,
const void *alloc_extension,
2347 VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
2354 VkMemoryAllocateInfo alloc_info = {
2355 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2356 .pNext = alloc_extension,
2357 .allocationSize = req->size,
2362 for (
int i = 0;
i < p->mprops.memoryTypeCount;
i++) {
2363 const VkMemoryType *
type = &p->mprops.memoryTypes[
i];
2366 if (!(req->memoryTypeBits & (1 <<
i)))
2370 if ((
type->propertyFlags & req_flags) != req_flags)
2374 if (req->size > p->mprops.memoryHeaps[
type->heapIndex].size)
2388 alloc_info.memoryTypeIndex =
index;
2390 ret = vk->AllocateMemory(dev_hwctx->
act_dev, &alloc_info,
2391 dev_hwctx->
alloc, mem);
2392 if (ret != VK_SUCCESS) {
2398 *mem_flags |= p->mprops.memoryTypes[
index].propertyFlags;
2412 if (internal->cuda_fc_ref) {
2418 CudaFunctions *cu = cu_internal->
cuda_dl;
2421 if (internal->cu_sem[
i])
2422 CHECK_CU(cu->cuDestroyExternalSemaphore(internal->cu_sem[
i]));
2423 if (internal->cu_mma[
i])
2424 CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[
i]));
2425 if (internal->ext_mem[
i])
2426 CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[
i]));
2428 if (internal->ext_sem_handle[
i])
2429 CloseHandle(internal->ext_sem_handle[
i]);
2430 if (internal->ext_mem_handle[
i])
2431 CloseHandle(internal->ext_mem_handle[
i]);
2439 if (internal->drm_sync_sem != VK_NULL_HANDLE)
2440 p->vkctx.vkfn.DestroySemaphore(p->p.act_dev, internal->drm_sync_sem,
2460 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
2462 .pSemaphores =
f->sem,
2463 .pValues =
f->sem_value,
2464 .semaphoreCount = nb_sems,
2472 for (
int i = 0;
i < nb_images;
i++) {
2487 void *alloc_pnext,
size_t alloc_pnext_stride)
2489 int img_cnt = 0, err;
2497 while (
f->img[img_cnt]) {
2499 VkImageMemoryRequirementsInfo2 req_desc = {
2500 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
2501 .image =
f->img[img_cnt],
2503 VkMemoryDedicatedAllocateInfo ded_alloc = {
2504 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
2505 .pNext = (
void *)(((uint8_t *)alloc_pnext) + img_cnt*alloc_pnext_stride),
2507 VkMemoryDedicatedRequirements ded_req = {
2508 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
2510 VkMemoryRequirements2 req = {
2511 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
2515 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req);
2518 "plane %d: driver reports prefersDedicatedAllocation=%i requiresDedicatedAllocation=%i\n",
2519 img_cnt, ded_req.prefersDedicatedAllocation, ded_req.requiresDedicatedAllocation);
2521 if (
f->tiling == VK_IMAGE_TILING_LINEAR)
2522 req.memoryRequirements.size =
FFALIGN(req.memoryRequirements.size,
2523 p->props.properties.limits.minMemoryMapAlignment);
2526 use_ded_mem = ded_req.prefersDedicatedAllocation |
2527 ded_req.requiresDedicatedAllocation;
2531 ded_alloc.image =
f->img[img_cnt];
2535 f->tiling == VK_IMAGE_TILING_LINEAR ?
2536 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
2537 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2538 use_ded_mem ? &ded_alloc : (
void *)ded_alloc.pNext,
2539 &
f->flags, &
f->mem[img_cnt])))
2542 f->size[img_cnt] = req.memoryRequirements.size;
2543 bind_info[img_cnt].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
2544 bind_info[img_cnt].image =
f->img[img_cnt];
2545 bind_info[img_cnt].memory =
f->mem[img_cnt];
2551 ret = vk->BindImageMemory2(hwctx->
act_dev, img_cnt, bind_info);
2552 if (ret != VK_SUCCESS) {
2572 VkAccessFlags2 *new_access)
2576 *new_layout = VK_IMAGE_LAYOUT_GENERAL;
2577 *new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2580 *new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
2581 *new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2584 *new_layout = VK_IMAGE_LAYOUT_GENERAL;
2585 *new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2588 *new_layout = VK_IMAGE_LAYOUT_GENERAL;
2589 *new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2592 *new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR;
2593 *new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2596 *new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR;
2597 *new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2600 *new_layout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR;
2601 *new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2615 VkImageLayout new_layout;
2616 VkAccessFlags2 new_access;
2619 uint32_t dst_qf = p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED : p->img_qfs[0];
2620 VkPipelineStageFlagBits2 src_stage = VK_PIPELINE_STAGE_2_NONE;
2622 dst_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR;
2623 src_stage = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
2630 .data = (uint8_t *)hwfc,
2633 .data[0] = (uint8_t *)
frame,
2634 .hw_frames_ctx = &tmp_ref,
2637 VkCommandBuffer cmd_buf;
2639 cmd_buf = exec->
buf;
2645 VK_PIPELINE_STAGE_2_NONE,
2646 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
2652 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
2653 new_access, new_layout, dst_qf);
2655 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
2656 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
2657 .pImageMemoryBarriers = img_bar,
2658 .imageMemoryBarrierCount = nb_img_bar,
2680 VkImageLayout new_layout;
2681 VkAccessFlags2 new_access;
2685 for (
i = 0;
i < p->vkctx.host_image_props.copyDstLayoutCount;
i++) {
2686 if (p->vkctx.host_image_props.pCopyDstLayouts[
i] == new_layout)
2689 if (
i == p->vkctx.host_image_props.copyDstLayoutCount)
2692 for (
i = 0;
i < nb_images;
i++) {
2693 layout_change[
i] = (VkHostImageLayoutTransitionInfoEXT) {
2694 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT,
2696 .oldLayout =
frame->layout[
i],
2697 .newLayout = new_layout,
2698 .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
2699 .subresourceRange.layerCount = 1,
2700 .subresourceRange.levelCount = 1,
2702 frame->layout[
i] = new_layout;
2705 ret = vk->TransitionImageLayoutEXT(p->vkctx.hwctx->act_dev,
2706 nb_images, layout_change);
2707 if (ret != VK_SUCCESS) {
2721 if (hwfc_vk->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT &&
2733 int frame_w,
int frame_h,
int plane)
2750 VkImageTiling tiling, VkImageUsageFlagBits
usage,
2751 VkImageCreateFlags
flags,
int nb_layers,
2763 VkSemaphoreTypeCreateInfo sem_type_info = {
2764 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2765 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2768 VkSemaphoreCreateInfo sem_spawn = {
2769 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2770 .pNext = &sem_type_info,
2773 VkExportSemaphoreCreateInfo ext_sem_info_opaque = {
2774 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
2776 .handleTypes = IsWindows8OrGreater()
2777 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2778 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
2780 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
2785 if (p->ext_sem_props_opaque.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) {
2799 for (
int i = 0; (hwfc_vk->
format[
i] != VK_FORMAT_UNDEFINED);
i++) {
2800 VkImageCreateInfo create_info = {
2801 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2802 .pNext = create_pnext,
2803 .imageType = VK_IMAGE_TYPE_2D,
2807 .arrayLayers = nb_layers,
2810 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2812 .samples = VK_SAMPLE_COUNT_1_BIT,
2813 .pQueueFamilyIndices = p->img_qfs,
2814 .queueFamilyIndexCount = p->nb_img_qfs,
2815 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2816 VK_SHARING_MODE_EXCLUSIVE,
2819 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
2822 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
2824 if (ret != VK_SUCCESS) {
2832 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
2834 if (ret != VK_SUCCESS) {
2841 f->queue_family[
i] = p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED : p->img_qfs[0];
2842 f->layout[
i] = create_info.initialLayout;
2844 f->sem_value[
i] = 0;
2860 VkExternalMemoryHandleTypeFlags *comp_handle_types,
2861 VkExternalMemoryHandleTypeFlags *iexp,
2862 VkExternalMemoryHandleTypeFlagBits
exp)
2870 const VkImageDrmFormatModifierListCreateInfoEXT *drm_mod_info =
2872 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
2873 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && drm_mod_info;
2876 VkExternalImageFormatProperties eprops = {
2877 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
2879 VkImageFormatProperties2 props = {
2880 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
2883 VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
2884 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
2886 .pQueueFamilyIndices = p->img_qfs,
2887 .queueFamilyIndexCount = p->nb_img_qfs,
2888 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2889 VK_SHARING_MODE_EXCLUSIVE,
2891 VkPhysicalDeviceExternalImageFormatInfo enext = {
2892 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
2894 .pNext = has_mods ? &phy_dev_mod_info :
NULL,
2896 VkPhysicalDeviceImageFormatInfo2 pinfo = {
2897 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
2898 .pNext = !
exp ?
NULL : &enext,
2899 .format = hwctx->
format[0],
2900 .type = VK_IMAGE_TYPE_2D,
2902 .usage = hwctx->
usage,
2903 .flags = (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && has_mods) ?
2907 nb_mods = has_mods ? drm_mod_info->drmFormatModifierCount : 1;
2908 for (
int i = 0;
i < nb_mods;
i++) {
2910 phy_dev_mod_info.drmFormatModifier = drm_mod_info->pDrmFormatModifiers[
i];
2912 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
2916 av_log(hwfc,
AV_LOG_VERBOSE,
"GetPhysicalDeviceImageFormatProperties2: mod[%d]=0x%llx -> %s\n",
2917 i, (
unsigned long long)phy_dev_mod_info.drmFormatModifier,
2918 ret == VK_SUCCESS ?
"OK" :
"FAIL");
2919 if (ret == VK_SUCCESS) {
2921 *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes;
2922 if (
exp == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) {
2925 VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT);
2933 VkExternalMemoryHandleTypeFlags *comp_handle_types,
2934 VkExternalMemoryHandleTypeFlags *export_types)
2939 *comp_handle_types = 0x0;
2940 *export_types = 0x0;
2944 try_export_flags(hwfc, comp_handle_types, export_types, IsWindows8OrGreater()
2945 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
2946 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
2949 (hwctx->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
2951 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
2954 hwctx->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
2956 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
2968 VkExternalMemoryHandleTypeFlags e;
2971 VkExternalMemoryImageCreateInfo eiinfo = {
2972 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
2979 eminfo[
i].sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
2981 eminfo[
i].handleTypes = e;
2988 av_log(hwfc,
AV_LOG_ERROR,
"vulkan_pool_alloc failed: create_frame failed: %d\n", err);
2996 if ( (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2997 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR))
2999 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)
3001 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR)
3003 else if (hwctx->
usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)
3070 if (p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
3073 "NVIDIA drivers mishandle multi-plane images\n");
3077 const VkImageDrmFormatModifierListCreateInfoEXT *mod_list =
3079 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
3080 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
3081 mod_list && mod_list->drmFormatModifierCount;
3082 int nb_mods = has_mods ? mod_list->drmFormatModifierCount : 1;
3085 if (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && !has_mods)
3088 VkPhysicalDeviceImageDrmFormatModifierInfoEXT mod_info = {
3089 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
3090 .pQueueFamilyIndices = p->img_qfs,
3091 .queueFamilyIndexCount = p->nb_img_qfs,
3092 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3093 VK_SHARING_MODE_EXCLUSIVE,
3095 VkPhysicalDeviceImageFormatInfo2 pinfo = {
3096 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3097 .type = VK_IMAGE_TYPE_2D,
3099 .usage = hwctx->
usage,
3106 VkVideoProfileListInfoKHR profile_list;
3107 const VkVideoProfileListInfoKHR *pl =
3109 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
3112 profile_list.pNext =
NULL;
3116 VkImageFormatListCreateInfo format_list;
3117 const VkImageFormatListCreateInfo *fl =
3119 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO);
3122 format_list.pNext =
NULL;
3129 hwctx->
format[
i] != VK_FORMAT_UNDEFINED;
i++) {
3130 pinfo.format = hwctx->
format[
i];
3134 for (
int j = 0; j < nb_mods; j++) {
3135 VkHostImageCopyDevicePerformanceQueryEXT perf = {
3136 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY_EXT,
3138 VkImageFormatProperties2 props = {
3139 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
3144 mod_info.drmFormatModifier = mod_list->pDrmFormatModifiers[j];
3146 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
3148 if (ret != VK_SUCCESS) {
3150 "format %i is not supported: %s\n",
3155 if (!perf.optimalDeviceAccess) {
3157 "format %i has no optimal device access (identical "
3158 "memory layout: %i)\n",
3159 pinfo.format, perf.identicalMemoryLayout);
3165 if (!p->vkctx.host_image_props.identicalMemoryTypeRequirements) {
3167 VkExternalMemoryHandleTypeFlags e;
3168 VkExternalMemoryImageCreateInfo eiinfo = {
3169 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
3173 VkImageCreateInfo create_info = {
3174 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3175 .pNext = eiinfo.handleTypes ? &eiinfo : hwctx->
create_pnext,
3176 .imageType = VK_IMAGE_TYPE_2D,
3177 .format = hwctx->
format[0],
3183 .usage = hwctx->
usage,
3184 .samples = VK_SAMPLE_COUNT_1_BIT,
3185 .pQueueFamilyIndices = p->img_qfs,
3186 .queueFamilyIndexCount = p->nb_img_qfs,
3187 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3188 VK_SHARING_MODE_EXCLUSIVE,
3190 VkDeviceImageMemoryRequirements req_info = {
3191 .sType = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS,
3192 .pCreateInfo = &create_info,
3193 .planeAspect = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT ?
3194 VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT : 0,
3196 VkMemoryRequirements2 req = {
3197 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3200 vk->GetDeviceImageMemoryRequirements(dev_hwctx->
act_dev, &req_info, &req);
3202 VkMemoryPropertyFlags req_flags = hwctx->
tiling == VK_IMAGE_TILING_LINEAR ?
3203 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
3204 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
3206 if (!(req.memoryRequirements.memoryTypeBits & (1U <<
index)))
3208 if ((p->mprops.memoryTypes[
index].propertyFlags & req_flags) == req_flags)
3211 if (
index == p->mprops.memoryTypeCount) {
3213 "no compatible memory type\n");
3229 VkImageUsageFlags supported_usage;
3233 int disable_multiplane = p->disable_multiplane ||
3235 int is_lone_dpb = ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR) ||
3236 ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
3237 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)));
3244 if (p->use_linear_images &&
3245 (hwctx->
tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
3246 hwctx->
tiling = VK_IMAGE_TILING_LINEAR;
3258 if ((hwfc->
width & ((1 <<
desc->log2_chroma_w) - 1)) ||
3259 (hwfc->
height & ((1 <<
desc->log2_chroma_h) - 1)))
3260 disable_multiplane = 1;
3262 if (hwctx->
format[0] != VK_FORMAT_UNDEFINED) {
3267 "for the current sw_format %s!\n",
3279 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
3288 NULL, &supported_usage,
3291 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
3300 int drm_mod_with_video = (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
3302 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR));
3304 if (!is_lone_dpb && !drm_mod_with_video) {
3306 hwctx->
usage |= supported_usage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT |
3307 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3308 VK_IMAGE_USAGE_STORAGE_BIT |
3309 VK_IMAGE_USAGE_SAMPLED_BIT);
3317 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR))
3318 hwctx->
usage |= supported_usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
3321 if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
3324 hwctx->
usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
3330 int sampleable = hwctx->
usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
3331 VK_IMAGE_USAGE_STORAGE_BIT);
3332 hwctx->
img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
3334 hwctx->
img_flags |= VK_IMAGE_CREATE_ALIAS_BIT;
3336 hwctx->
img_flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
3345 if ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
3348 const VkVideoProfileListInfoKHR *pl;
3351 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
3354 for (
i = 0;
i < pl->profileCount;
i++) {
3356 if (pl->pProfiles[
i].videoCodecOperation & 0xFFFF0000)
3359 if (
i == pl->profileCount)
3360 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
3365 if ((hwctx->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT) &&
3367 hwctx->
usage &= ~VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
3398 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
3399 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
3401 err = vk->GetImageDrmFormatModifierPropertiesEXT(dev_hwctx->
act_dev,
f->img[0],
3403 if (err != VK_SUCCESS) {
3409 VkDrmFormatModifierPropertiesListEXT modp;
3410 VkFormatProperties2 fmtp;
3411 VkDrmFormatModifierPropertiesEXT *mod_props =
NULL;
3413 modp = (VkDrmFormatModifierPropertiesListEXT) {
3414 .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
3416 fmtp = (VkFormatProperties2) {
3417 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
3422 vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->
phys_dev, fmt->
fallback[
i], &fmtp);
3424 modp.pDrmFormatModifierProperties =
3425 av_calloc(modp.drmFormatModifierCount,
sizeof(*modp.pDrmFormatModifierProperties));
3426 if (!modp.pDrmFormatModifierProperties) {
3430 vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->
phys_dev, fmt->
fallback[
i], &fmtp);
3432 for (uint32_t j = 0; j < modp.drmFormatModifierCount; ++j) {
3433 VkDrmFormatModifierPropertiesEXT *m = &modp.pDrmFormatModifierProperties[j];
3434 if (m->drmFormatModifier == drm_mod.drmFormatModifier) {
3440 if (mod_props ==
NULL) {
3441 av_log(hwfc,
AV_LOG_ERROR,
"No DRM format modifier properties found for modifier 0x%016"PRIx64
"\n",
3442 drm_mod.drmFormatModifier);
3443 av_free(modp.pDrmFormatModifierProperties);
3449 av_free(modp.pDrmFormatModifierProperties);
3513static const struct {
3514 uint32_t drm_fourcc;
3516} vulkan_drm_format_map[] = {
3517 { DRM_FORMAT_R8, VK_FORMAT_R8_UNORM },
3518 { DRM_FORMAT_R16, VK_FORMAT_R16_UNORM },
3519 { DRM_FORMAT_GR88, VK_FORMAT_R8G8_UNORM },
3520 { DRM_FORMAT_RG88, VK_FORMAT_R8G8_UNORM },
3521 { DRM_FORMAT_GR1616, VK_FORMAT_R16G16_UNORM },
3522 { DRM_FORMAT_RG1616, VK_FORMAT_R16G16_UNORM },
3523 { DRM_FORMAT_ARGB8888, VK_FORMAT_B8G8R8A8_UNORM },
3524 { DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM },
3525 { DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM },
3526 { DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM },
3527 { DRM_FORMAT_ARGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
3528 { DRM_FORMAT_ABGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
3529 { DRM_FORMAT_XRGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
3530 { DRM_FORMAT_XBGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
3533#ifdef DRM_FORMAT_XYUV8888
3534 { DRM_FORMAT_XYUV8888, VK_FORMAT_R8G8B8A8_UNORM },
3535 { DRM_FORMAT_XVYU2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 } ,
3536 { DRM_FORMAT_XVYU12_16161616, VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 } ,
3537 { DRM_FORMAT_XVYU16161616, VK_FORMAT_R16G16B16A16_UNORM } ,
3541static inline VkFormat drm_to_vulkan_fmt(uint32_t drm_fourcc)
3544 if (vulkan_drm_format_map[
i].drm_fourcc == drm_fourcc)
3545 return vulkan_drm_format_map[
i].vk_format;
3546 return VK_FORMAT_UNDEFINED;
3555 int bind_counts = 0;
3564 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3565 if (drm_to_vulkan_fmt(
desc->layers[
i].format) == VK_FORMAT_UNDEFINED) {
3567 desc->layers[
i].format);
3578 f->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
3580 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3584 VkSemaphoreTypeCreateInfo sem_type_info = {
3585 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3586 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
3589 VkSemaphoreCreateInfo sem_spawn = {
3590 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3591 .pNext = &sem_type_info,
3596 VkImageDrmFormatModifierExplicitCreateInfoEXT ext_img_mod_spec = {
3597 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
3598 .drmFormatModifier =
desc->objects[0].format_modifier,
3599 .drmFormatModifierPlaneCount =
planes,
3600 .pPlaneLayouts = (
const VkSubresourceLayout *)&ext_img_layouts,
3602 VkExternalMemoryImageCreateInfo ext_img_spec = {
3603 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
3604 .pNext = &ext_img_mod_spec,
3605 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3607 VkImageCreateInfo create_info = {
3608 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3609 .pNext = &ext_img_spec,
3610 .imageType = VK_IMAGE_TYPE_2D,
3611 .format = drm_to_vulkan_fmt(
desc->layers[
i].format),
3616 .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
3617 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
3619 .samples = VK_SAMPLE_COUNT_1_BIT,
3620 .pQueueFamilyIndices =
p->img_qfs,
3621 .queueFamilyIndexCount =
p->nb_img_qfs,
3622 .sharingMode =
p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3623 VK_SHARING_MODE_EXCLUSIVE,
3634 if (sw_vkfmts && sw_vkfmts[
i] != VK_FORMAT_UNDEFINED)
3635 create_info.format = sw_vkfmts[
i];
3639 VkExternalImageFormatProperties ext_props = {
3640 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
3642 VkImageFormatProperties2 props_ret = {
3643 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
3644 .pNext = &ext_props,
3646 VkPhysicalDeviceImageDrmFormatModifierInfoEXT props_drm_mod = {
3647 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
3648 .drmFormatModifier = ext_img_mod_spec.drmFormatModifier,
3649 .pQueueFamilyIndices = create_info.pQueueFamilyIndices,
3650 .queueFamilyIndexCount = create_info.queueFamilyIndexCount,
3651 .sharingMode = create_info.sharingMode,
3653 VkPhysicalDeviceExternalImageFormatInfo props_ext = {
3654 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
3655 .pNext = &props_drm_mod,
3656 .handleType = ext_img_spec.handleTypes,
3658 VkPhysicalDeviceImageFormatInfo2 fmt_props;
3661 create_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT |
3662 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3664 create_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT |
3665 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3667 fmt_props = (VkPhysicalDeviceImageFormatInfo2) {
3668 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3669 .pNext = &props_ext,
3670 .format = create_info.format,
3671 .type = create_info.imageType,
3672 .tiling = create_info.tiling,
3673 .usage = create_info.usage,
3674 .flags = create_info.flags,
3678 ret = vk->GetPhysicalDeviceImageFormatProperties2(hwctx->phys_dev,
3679 &fmt_props, &props_ret);
3680 if (ret != VK_SUCCESS) {
3688 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
3689 hwfc->sw_format,
src->width,
src->height,
i);
3692 for (
int j = 0; j <
planes; j++) {
3693 ext_img_layouts[j].offset =
desc->layers[
i].planes[j].offset;
3694 ext_img_layouts[j].rowPitch =
desc->layers[
i].planes[j].pitch;
3695 ext_img_layouts[j].size = 0;
3696 ext_img_layouts[j].arrayPitch = 0;
3697 ext_img_layouts[j].depthPitch = 0;
3701 ret = vk->CreateImage(hwctx->act_dev, &create_info,
3702 hwctx->alloc, &
f->img[
i]);
3703 if (ret != VK_SUCCESS) {
3710 ret = vk->CreateSemaphore(hwctx->act_dev, &sem_spawn,
3711 hwctx->alloc, &
f->sem[
i]);
3712 if (ret != VK_SUCCESS) {
3719 f->queue_family[
i] = VK_QUEUE_FAMILY_EXTERNAL;
3720 f->layout[
i] = create_info.initialLayout;
3722 f->sem_value[
i] = 0;
3725 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3727 VkImageMemoryRequirementsInfo2 req_desc = {
3728 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
3731 VkMemoryDedicatedRequirements ded_req = {
3732 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
3734 VkMemoryRequirements2 req2 = {
3735 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3740 VkMemoryFdPropertiesKHR fdmp = {
3741 .sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR,
3747 VkImportMemoryFdInfoKHR idesc = {
3748 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
3749 .fd = dup(
desc->objects[
desc->layers[
i].planes[0].object_index].fd),
3750 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3752 VkMemoryDedicatedAllocateInfo ded_alloc = {
3753 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
3755 .image = req_desc.image,
3759 ret = vk->GetMemoryFdPropertiesKHR(hwctx->act_dev,
3760 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3762 if (ret != VK_SUCCESS) {
3770 vk->GetImageMemoryRequirements2(hwctx->act_dev, &req_desc, &req2);
3773 req2.memoryRequirements.memoryTypeBits = fdmp.memoryTypeBits;
3776 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
3777 (ded_req.prefersDedicatedAllocation ||
3778 ded_req.requiresDedicatedAllocation) ?
3779 &ded_alloc : ded_alloc.pNext,
3780 &
f->flags, &
f->mem[
i]);
3786 f->size[
i] = req2.memoryRequirements.size;
3789 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3791 for (
int j = 0; j <
planes; j++) {
3792 VkImageAspectFlagBits aspect = j == 0 ? VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT :
3793 j == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3794 VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
3796 plane_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO;
3798 plane_info[bind_counts].planeAspect = aspect;
3800 bind_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
3802 bind_info[bind_counts].image =
f->img[
i];
3803 bind_info[bind_counts].memory =
f->mem[
i];
3806 bind_info[bind_counts].memoryOffset = 0;
3813 ret = vk->BindImageMemory2(hwctx->act_dev, bind_counts, bind_info);
3814 if (ret != VK_SUCCESS) {
3842#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
3844 VkCommandBuffer cmd_buf;
3850 for (
int i = 0;
i <
desc->nb_objects;
i++) {
3851 VkSemaphoreTypeCreateInfo sem_type_info = {
3852 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3853 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
3855 VkSemaphoreCreateInfo sem_spawn = {
3856 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3857 .pNext = &sem_type_info,
3859 VkImportSemaphoreFdInfoKHR import_info;
3860 struct dma_buf_export_sync_file implicit_fd_info = {
3861 .flags = DMA_BUF_SYNC_READ,
3865 if (ioctl(
desc->objects[
i].fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE,
3866 &implicit_fd_info)) {
3871 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3875 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3876 hwctx->
alloc, &drm_sync_sem[
i]);
3877 if (ret != VK_SUCCESS) {
3882 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3886 import_info = (VkImportSemaphoreFdInfoKHR) {
3887 .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
3888 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
3889 .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
3890 .semaphore = drm_sync_sem[
i],
3891 .fd = implicit_fd_info.fd,
3894 ret = vk->ImportSemaphoreFdKHR(hwctx->
act_dev, &import_info);
3895 if (ret != VK_SUCCESS) {
3900 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3906 cmd_buf = exec->
buf;
3910 for (
int i = 0;
i <
desc->nb_objects;
i++)
3911 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3917 drm_sync_sem,
desc->nb_objects,
3918 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 1);
3921 VK_PIPELINE_STAGE_2_NONE,
3922 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
3929 VK_PIPELINE_STAGE_2_NONE,
3930 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
3932 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT : 0x0) |
3934 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT : 0x0),
3935 VK_IMAGE_LAYOUT_GENERAL,
3936 p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED :
p->img_qfs[0]);
3938 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
3939 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
3940 .pImageMemoryBarriers = img_bar,
3941 .imageMemoryBarrierCount = nb_img_bar,
3952 "image may be corrupted.\n");
3968 if ((err = vulkan_map_from_drm_frame_desc(hwfc, &
f,
src,
flags)))
3972 dst->data[0] = (uint8_t *)
f;
3974 dst->height =
src->height;
3977 &vulkan_unmap_from_drm,
f);
3981 err = vulkan_map_from_drm_frame_sync(hwfc,
dst,
desc,
flags);
4004 VASurfaceID surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
4010 vaSyncSurface(vaapi_ctx->
display, surface_id);
4018 err = vulkan_map_from_drm(dst_fc,
dst,
tmp,
flags);
4035 VkDeviceMemory mem,
size_t size)
4043 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
4044 .type = IsWindows8OrGreater()
4045 ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
4046 : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT,
4049 VkMemoryGetWin32HandleInfoKHR export_info = {
4050 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
4052 .handleType = IsWindows8OrGreater()
4053 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
4054 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
4057 ret = vk->GetMemoryWin32HandleKHR(hwctx->
act_dev, &export_info,
4058 &ext_desc.handle.win32.handle);
4059 if (ret != VK_SUCCESS) {
4064 dst_int->ext_mem_handle[idx] = ext_desc.handle.win32.handle;
4066 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
4067 .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
4070 VkMemoryGetFdInfoKHR export_info = {
4071 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
4073 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
4076 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
4077 &ext_desc.handle.fd);
4078 if (ret != VK_SUCCESS) {
4085 ret =
CHECK_CU(cu->cuImportExternalMemory(&dst_int->ext_mem[idx], &ext_desc));
4088 close(ext_desc.handle.fd);
4107 VkSemaphoreGetWin32HandleInfoKHR sem_export = {
4108 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
4110 .handleType = IsWindows8OrGreater()
4111 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
4112 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
4114 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
4118 VkSemaphoreGetFdInfoKHR sem_export = {
4119 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
4121 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
4123 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
4129 ret = vk->GetSemaphoreWin32HandleKHR(hwctx->
act_dev, &sem_export,
4130 &ext_sem_desc.handle.win32.handle);
4132 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &sem_export,
4133 &ext_sem_desc.handle.fd);
4135 if (ret != VK_SUCCESS) {
4141 dst_int->ext_sem_handle[idx] = ext_sem_desc.handle.win32.handle;
4144 ret =
CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[idx],
4148 close(ext_sem_desc.handle.fd);
4176 CudaFunctions *cu = cu_internal->
cuda_dl;
4177 CUarray_format cufmt =
desc->comp[0].depth > 8 ? CU_AD_FORMAT_UNSIGNED_INT16 :
4178 CU_AD_FORMAT_UNSIGNED_INT8;
4179 const int elem_size = 1 + (
desc->comp[0].depth > 8);
4182 dst_int = dst_f->internal;
4184 if (!dst_int->cuda_fc_ref) {
4188 if (!dst_int->cuda_fc_ref)
4192 for (
int i = 0;
i < nb_images;
i++) {
4193 err = export_mem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
4194 dst_f->mem[
i], dst_f->size[
i]);
4198 err = export_sem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
4204 if (nb_images !=
planes) {
4208 if (
desc->comp[
i].step / elem_size > 1) {
4210 "Cannot map a multiplane Vulkan image (%d image(s) "
4211 "for %d plane(s)) to CUDA; create the Vulkan device "
4212 "with the disable_multiplane=1 option (one image per "
4213 "plane) for CUDA interop.\n", nb_images,
planes);
4218 VkImageSubresource subres = {
4219 .aspectMask =
i == 2 ? VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT :
4220 i == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
4221 VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT
4223 VkSubresourceLayout
layout = { 0 };
4224 vk->GetImageSubresourceLayout(hwctx->
act_dev, dst_f->img[
FFMIN(
i, nb_images - 1)],
4231 CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = {
4236 .NumChannels =
desc->comp[
i].step / elem_size,
4244 tex_desc.arrayDesc.Width = p_w;
4245 tex_desc.arrayDesc.Height = p_h;
4247 ret =
CHECK_CU(cu->cuExternalMemoryGetMappedMipmappedArray(&dst_int->cu_mma[
i],
4248 dst_int->ext_mem[
FFMIN(
i, nb_images - 1)],
4255 ret =
CHECK_CU(cu->cuMipmappedArrayGetLevel(&dst_int->cu_array[
i],
4256 dst_int->cu_mma[
i], 0));
4289 CudaFunctions *cu = cu_internal->
cuda_dl;
4300 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
4304 err = vulkan_export_to_cuda(hwfc,
src->hw_frames_ctx,
dst);
4310 dst_int = dst_f->internal;
4312 for (
int i = 0;
i < nb_images;
i++) {
4313 s_w_par[
i].params.fence.value = dst_f->sem_value[
i] + 0;
4314 s_s_par[
i].params.fence.value = dst_f->sem_value[
i] + 1;
4317 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
4318 nb_images, cuda_dev->stream));
4323 CUDA_MEMCPY2D cpy = {
4324 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
4325 .srcDevice = (CUdeviceptr)
src->data[
i],
4326 .srcPitch =
src->linesize[
i],
4329 .dstMemoryType = CU_MEMORYTYPE_ARRAY,
4330 .dstArray = dst_int->cu_array[
i],
4336 cpy.WidthInBytes = p_w *
desc->comp[
i].step;
4339 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
4344 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
4345 nb_images, cuda_dev->stream));
4349 for (
int i = 0;
i < nb_images;
i++)
4350 dst_f->sem_value[
i]++;
4371 switch (
src->format) {
4376 return vulkan_map_from_vaapi(hwfc,
dst,
src,
flags);
4382 return vulkan_map_from_drm(hwfc,
dst,
src,
flags);
4392typedef struct VulkanDRMMapping {
4393 AVDRMFrameDescriptor drm_desc;
4411static inline uint32_t vulkan_fmt_to_drm(
VkFormat vkfmt)
4414 if (vulkan_drm_format_map[
i].vk_format == vkfmt)
4415 return vulkan_drm_format_map[
i].drm_fourcc;
4416 return DRM_FORMAT_INVALID;
4419#define MAX_MEMORY_PLANES 4
4420static VkImageAspectFlags plane_index_to_aspect(
int plane) {
4421 if (plane == 0)
return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
4422 if (plane == 1)
return VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT;
4423 if (plane == 2)
return VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
4424 if (plane == 3)
return VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT;
4427 return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
4430#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
4440 if (
f->internal->drm_sync_sem == VK_NULL_HANDLE) {
4441 VkExportSemaphoreCreateInfo exp_info = {
4442 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
4443 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
4445 VkSemaphoreTypeCreateInfo type_info = {
4446 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
4448 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
4450 VkSemaphoreCreateInfo sem_create = {
4451 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
4452 .pNext = &type_info,
4454 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_create, hwctx->
alloc,
4455 &
f->internal->drm_sync_sem);
4456 if (ret != VK_SUCCESS) {
4468 for (
int i = 0;
i < nb_sems;
i++)
4471 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
4473 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 0);
4475 VkSemaphoreGetFdInfoKHR get_fd_info = {
4476 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
4477 .semaphore =
f->internal->drm_sync_sem,
4478 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
4480 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &get_fd_info, &sync_fd);
4481 if (ret != VK_SUCCESS) {
4483 "Failed to get sync fd from DRM map export semaphore: %s\n",
4506 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
4507 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
4509 const int nb_sems = nb_images;
4510 int free_drm_desc_on_err = 1;
4521#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
4523 f->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
4524 vk->GetSemaphoreFdKHR && vk->CreateSemaphore) {
4525 err = vulkan_drm_export_sync_fd(hwfc,
f, fp, nb_sems);
4534 VkSemaphoreWaitInfo wait_info = {
4535 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
4537 .semaphoreCount = nb_sems,
4538 .pSemaphores =
f->sem,
4539 .pValues =
f->sem_value,
4541 vk->WaitSemaphores(hwctx->
act_dev, &wait_info, UINT64_MAX);
4549 free_drm_desc_on_err = 0;
4551 ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->
act_dev,
f->img[0],
4553 if (ret != VK_SUCCESS) {
4559 for (
int i = 0; (
i <
planes) && (
f->mem[
i]);
i++) {
4560 VkMemoryGetFdInfoKHR export_info = {
4561 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
4562 .memory =
f->mem[
i],
4563 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
4566 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
4568 if (ret != VK_SUCCESS) {
4574#if HAVE_LINUX_DMA_BUF_H && defined(DMA_BUF_IOCTL_IMPORT_SYNC_FILE)
4576 int dup_fd = dup(sync_fd);
4578 struct dma_buf_import_sync_file import_info = {
4579 .flags = DMA_BUF_SYNC_WRITE,
4582 if (ioctl(drm_desc->
objects[
i].
fd, DMA_BUF_IOCTL_IMPORT_SYNC_FILE, &import_info) < 0)
4601 drm_desc->
layers[
i].
format = vulkan_fmt_to_drm(plane_vkfmt);
4611 VkSubresourceLayout
layout;
4612 int aspect_plane = (nb_images == 1) ?
i : j;
4613 VkImageSubresource sub = {
4614 .aspectMask = plane_index_to_aspect(aspect_plane),
4631 if (
f->tiling == VK_IMAGE_TILING_OPTIMAL)
4637 dst->height =
src->height;
4638 dst->data[0] = (uint8_t *)drm_desc;
4651 if (free_drm_desc_on_err)
4691 switch (
dst->format) {
4701 return vulkan_map_to_vaapi(hwfc,
dst,
src,
flags);
4713 AVFrame *swf, VkBufferImageCopy *region,
4722 region[
i].bufferRowLength,
4726 region[
i].imageExtent.height);
4729 if (err != VK_SUCCESS) {
4736 if (err != VK_SUCCESS) {
4746 region[
i].bufferRowLength,
4748 region[
i].imageExtent.height);
4755 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4762 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4763 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4765 size_t buf_offset = 0;
4769 region[
i] = (VkBufferImageCopy) {
4770 .bufferOffset = buf_offset,
4772 p->props.properties.limits.optimalBufferCopyRowPitchAlignment),
4773 .bufferImageHeight = p_h,
4774 .imageSubresource.layerCount = 1,
4775 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4779 buf_offset +=
FFALIGN(p_h*region[
i].bufferRowLength,
4780 p->props.properties.limits.optimalBufferCopyOffsetAlignment);
4785 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
4786 p->vkctx.host_cached_flag);
4794 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4802 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4803 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4807 while (swf->
buf[nb_src_bufs])
4811 if (nb_src_bufs == 1) {
4813 swf->
data[0], VK_WHOLE_SIZE, swf->
buf[0],
4820 region[
i].bufferOffset =
dst[0]->virtual_offset +
4822 }
else if (nb_src_bufs ==
planes) {
4825 swf->
data[
i], VK_WHOLE_SIZE,
4826 swf->
buf[
i], buf_usage);
4831 region[
i].bufferOffset =
dst[
i]->virtual_offset;
4852 for (
int i = 0;
i < (*nb_bufs);
i++)
4873 int nb_layout_ch = 0;
4877 for (
int i = 0;
i < nb_images;
i++) {
4879 for (
int j = 0; j < p->vkctx.host_image_props.copySrcLayoutCount; j++) {
4880 if (hwf_vk->
layout[
i] == p->vkctx.host_image_props.pCopySrcLayouts[j]) {
4890 layout_ch_info[nb_layout_ch] = (VkHostImageLayoutTransitionInfoEXT) {
4891 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT,
4892 .image = hwf_vk->
img[
i],
4893 .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
4894 .newLayout = VK_IMAGE_LAYOUT_GENERAL,
4895 .subresourceRange = {
4896 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4902 hwf_vk->
layout[
i] = layout_ch_info[nb_layout_ch].newLayout;
4907 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
4908 .pSemaphores = hwf_vk->
sem,
4910 .semaphoreCount = nb_images,
4916 vk->TransitionImageLayoutEXT(hwctx->
act_dev,
4917 nb_layout_ch, layout_ch_info);
4920 VkMemoryToImageCopyEXT region_info = {
4921 .sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT,
4922 .imageSubresource = {
4926 VkCopyMemoryToImageInfoEXT copy_info = {
4927 .sType = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT,
4929 .pRegions = ®ion_info,
4932 int img_idx =
FFMIN(
i, (nb_images - 1));
4936 region_info.pHostPointer = swf->
data[
i];
4937 region_info.memoryRowLength = swf->
linesize[
i] /
desc->comp[
i].step;
4939 region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 };
4940 copy_info.dstImage = hwf_vk->
img[img_idx];
4941 copy_info.dstImageLayout = hwf_vk->
layout[img_idx];
4943 vk->CopyMemoryToImageEXT(hwctx->
act_dev, ©_info);
4946 VkImageToMemoryCopyEXT region_info = {
4947 .sType = VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT,
4948 .imageSubresource = {
4952 VkCopyImageToMemoryInfoEXT copy_info = {
4953 .sType = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT,
4955 .pRegions = ®ion_info,
4958 int img_idx =
FFMIN(
i, (nb_images - 1));
4962 region_info.pHostPointer = swf->
data[
i];
4963 region_info.memoryRowLength = swf->
linesize[
i] /
desc->comp[
i].step;
4965 region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 };
4966 copy_info.srcImage = hwf_vk->
img[img_idx];
4967 copy_info.srcImageLayout = hwf_vk->
layout[img_idx];
4969 vk->CopyImageToMemoryEXT(hwctx->
act_dev, ©_info);
4988 int host_mapped = 0;
5003 VkCommandBuffer cmd_buf;
5015 int host_copy = hwctx->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
5017 !p->avoid_host_import;
5023 host_copy = host_map = 0;
5026 if (!upload && host_copy) {
5027 for (
int i = 0;
i < nb_images;
i++) {
5029 for (
int j = 0; j < p->vkctx.host_image_props.copySrcLayoutCount; j++) {
5030 if (hwf_vk->
layout[
i] == p->vkctx.host_image_props.pCopySrcLayouts[j]) {
5050 region[
i] = (VkBufferImageCopy) {
5053 .bufferImageHeight = p_h,
5054 .imageSubresource.layerCount = 1,
5055 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
5081 cmd_buf = exec->
buf;
5089 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
5090 VK_PIPELINE_STAGE_2_TRANSFER_BIT);
5108 for (
int i = 0;
i < nb_bufs;
i++)
5113 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
5114 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,
5115 upload ? VK_ACCESS_TRANSFER_WRITE_BIT :
5116 VK_ACCESS_TRANSFER_READ_BIT,
5117 upload ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL :
5118 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5119 p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED : p->img_qfs[0]);
5121 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
5122 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
5123 .pImageMemoryBarriers = img_bar,
5124 .imageMemoryBarrierCount = nb_img_bar,
5128 int buf_idx =
FFMIN(
i, (nb_bufs - 1));
5129 int img_idx =
FFMIN(
i, (nb_images - 1));
5132 uint32_t orig_stride = region[
i].bufferRowLength;
5133 region[
i].bufferRowLength /=
desc->comp[
i].step;
5137 vk->CmdCopyBufferToImage(cmd_buf, vkbuf->
buf,
5138 hwf_vk->
img[img_idx],
5139 img_bar[img_idx].newLayout,
5142 vk->CmdCopyImageToBuffer(cmd_buf, hwf_vk->
img[img_idx],
5143 img_bar[img_idx].newLayout,
5147 region[
i].bufferRowLength = orig_stride;
5151 if (err >= 0 && !upload) {
5158 for (
int i = 0;
i < nb_bufs;
i++)
5169 switch (
src->format) {
5179 return vulkan_transfer_data_from_cuda(hwfc,
dst,
src);
5183 if (
src->hw_frames_ctx)
5208 CudaFunctions *cu = cu_internal->
cuda_dl;
5219 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
5223 err = vulkan_export_to_cuda(hwfc,
dst->hw_frames_ctx,
src);
5229 dst_int = dst_f->internal;
5231 for (
int i = 0;
i < nb_images;
i++) {
5232 s_w_par[
i].params.fence.value = dst_f->sem_value[
i] + 0;
5233 s_s_par[
i].params.fence.value = dst_f->sem_value[
i] + 1;
5236 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
5237 nb_images, cuda_dev->stream));
5242 CUDA_MEMCPY2D cpy = {
5243 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
5244 .dstDevice = (CUdeviceptr)
dst->data[
i],
5245 .dstPitch =
dst->linesize[
i],
5248 .srcMemoryType = CU_MEMORYTYPE_ARRAY,
5249 .srcArray = dst_int->cu_array[
i],
5255 cpy.WidthInBytes =
w *
desc->comp[
i].step;
5258 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
5263 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
5264 nb_images, cuda_dev->stream));
5268 for (
int i = 0;
i < nb_images;
i++)
5269 dst_f->sem_value[
i]++;
5290 switch (
dst->format) {
5300 return vulkan_transfer_data_to_cuda(hwfc,
dst,
src);
5304 if (
dst->hw_frames_ctx)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static const char *const format[]
static AVFormatContext * ctx
static AVDictionary * opts
static av_cold void close(AVCodecParserContext *s)
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
static const uint8_t *BS_FUNC align(BSCTX *bc)
Skip bits to a byte boundary.
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
#define AV_CEIL_RSHIFT(a, b)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static const uint16_t fc[]
#define AV_NUM_DATA_POINTERS
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
AVBufferPool * av_buffer_pool_init2(size_t size, void *opaque, AVBufferRef *(*alloc)(void *opaque, size_t size), void(*pool_free)(void *opaque))
Allocate and initialize a buffer pool with a more complex allocator.
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
#define AVERROR_EXTERNAL
Generic error in an external library.
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
#define LIBAVUTIL_VERSION_MINOR
#define LIBAVUTIL_VERSION_MAJOR
#define LIBAVUTIL_VERSION_MICRO
static const int offsets[]
static const int weights[]
int ff_hwframe_map_create(AVBufferRef *hwframe_ref, AVFrame *dst, const AVFrame *src, void(*unmap)(AVHWFramesContext *ctx, HWMapDescriptor *hwmap), void *priv)
int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
Map a hardware frame.
int ff_hwframe_map_replace(AVFrame *dst, const AVFrame *src)
Replace the current hwmap of dst with the one from src, used for indirect mappings like VAAPI->(DRM)-...
@ AV_HWFRAME_MAP_READ
The mapping must be readable.
@ AV_HWFRAME_MAP_WRITE
The mapping must be writeable.
AVHWFrameTransferDirection
@ AV_HWDEVICE_TYPE_VULKAN
FFmpeg internal API for CUDA.
API-specific header for AV_HWDEVICE_TYPE_DRM.
@ AV_DRM_MAX_PLANES
The maximum number of layers/planes in a DRM frame.
static FFHWFramesContext * ffhwframesctx(AVHWFramesContext *ctx)
const HWContextType ff_hwcontext_type_vulkan
const VkFormat * av_vkfmt_from_pixfmt(enum AVPixelFormat p)
Returns the optimal per-plane Vulkan format for a given sw_format, one for each plane.
API-specific header for AV_HWDEVICE_TYPE_VAAPI.
static int pick_queue_family(VkQueueFamilyProperties2 *qf, uint32_t num_qf, VkQueueFlagBits flags)
AVVkFrame * av_vk_frame_alloc(void)
Allocates a single AVVkFrame and initializes everything as 0.
#define PICK_QF(type, vid_op)
static void unlock_frame(AVHWFramesContext *fc, AVVkFrame *vkf)
static void vulkan_free_internal(VulkanDevicePriv *p, AVVkFrame *f)
static int vulkan_frames_init(AVHWFramesContext *hwfc)
static VKAPI_ATTR VkBool32 VKAPI_CALL vk_dbg_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *data, void *priv)
static int alloc_mem(AVHWDeviceContext *ctx, VkMemoryRequirements *req, VkMemoryPropertyFlagBits req_flags, const void *alloc_extension, VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
static int vulkan_transfer_data_to(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src)
#define RELEASE_PROPS(props, count)
static const struct FFVkFormatEntry vk_formats_list[]
static int vulkan_transfer_host(AVHWFramesContext *hwfc, AVFrame *hwf, AVFrame *swf, int upload)
static void device_features_init(AVHWDeviceContext *ctx, VulkanDeviceFeatures *feats)
static const int nb_vk_formats_list
static int pick_video_queue_family(VkQueueFamilyProperties2 *qf, VkQueueFamilyVideoPropertiesKHR *qf_vid, uint32_t num_qf, VkVideoCodecOperationFlagsKHR flags)
static const char * vk_dev_type(enum VkPhysicalDeviceType type)
static int alloc_bind_mem(AVHWFramesContext *hwfc, AVVkFrame *f, void *alloc_pnext, size_t alloc_pnext_stride)
static void device_features_copy_needed(VulkanDeviceFeatures *dst, VulkanDeviceFeatures *src)
const VkFormat * av_vkfmt_from_pixfmt(enum AVPixelFormat p)
Returns the optimal per-plane Vulkan format for a given sw_format, one for each plane.
static int switch_layout(AVHWFramesContext *hwfc, FFVkExecPool *ectx, AVVkFrame *frame, enum PrepMode pmode)
static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame, VkImageTiling tiling, VkImageUsageFlagBits usage, VkImageCreateFlags flags, int nb_layers, void *create_pnext)
static int vulkan_host_transfer_usable(AVHWFramesContext *hwfc)
static int setup_queue_families(AVHWDeviceContext *ctx, VkDeviceCreateInfo *cd)
static int find_device(AVHWDeviceContext *ctx, VulkanDeviceSelection *select)
static void vulkan_frame_free_cb(void *opaque, uint8_t *data)
#define ADD_VAL_TO_LIST(list, count, val)
static void get_export_handle_types(AVHWFramesContext *hwfc, VkExternalMemoryHandleTypeFlags *comp_handle_types, VkExternalMemoryHandleTypeFlags *export_types)
static int vulkan_frames_get_constraints(AVHWDeviceContext *ctx, const void *hwconfig, AVHWFramesConstraints *constraints)
static int copy_buffer_data(AVHWFramesContext *hwfc, FFVkBuffer *vkbuf, AVFrame *swf, VkBufferImageCopy *region, int planes, int upload)
static int vulkan_transfer_get_formats(AVHWFramesContext *hwfc, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
static void unlock_queue(AVHWDeviceContext *ctx, uint32_t queue_family, uint32_t index)
static int vulkan_device_derive(AVHWDeviceContext *ctx, AVHWDeviceContext *src_ctx, AVDictionary *opts, int flags)
static int vulkan_device_init(AVHWDeviceContext *ctx)
static int vulkan_frames_derive_to(AVHWFramesContext *dst_fc, AVHWFramesContext *src_fc, int flags)
@ FF_VULKAN_DEBUG_VALIDATE
@ FF_VULKAN_DEBUG_PRACTICES
static int prepare_frame(AVHWFramesContext *hwfc, FFVkExecPool *ectx, AVVkFrame *frame, enum PrepMode pmode)
static int vulkan_device_create(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags)
static int vulkan_transfer_data_from(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src)
static int vulkan_map_from(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src, int flags)
static void switch_new_props(enum PrepMode pmode, VkImageLayout *new_layout, VkAccessFlags2 *new_access)
static int vulkan_transfer_frame(AVHWFramesContext *hwfc, AVFrame *swf, AVFrame *hwf, int upload)
static int host_map_frame(AVHWFramesContext *hwfc, FFVkBuffer **dst, int *nb_bufs, AVFrame *swf, VkBufferImageCopy *region, int upload)
static void lock_frame(AVHWFramesContext *fc, AVVkFrame *vkf)
static AVBufferRef * vulkan_pool_alloc(void *opaque, size_t size)
static void vulkan_frame_free(AVHWFramesContext *hwfc, AVVkFrame *f)
static void vulkan_device_uninit(AVHWDeviceContext *ctx)
static void lock_queue(AVHWDeviceContext *ctx, uint32_t queue_family, uint32_t index)
static int vulkan_device_create_internal(AVHWDeviceContext *ctx, VulkanDeviceSelection *dev_select, int disable_multiplane, AVDictionary *opts, int flags)
static const struct FFVkFormatEntry * vk_find_format_entry(enum AVPixelFormat p)
static void try_export_flags(AVHWFramesContext *hwfc, VkExternalMemoryHandleTypeFlags *comp_handle_types, VkExternalMemoryHandleTypeFlags *iexp, VkExternalMemoryHandleTypeFlagBits exp)
static void vulkan_device_free(AVHWDeviceContext *ctx)
static void get_plane_wh(uint32_t *w, uint32_t *h, enum AVPixelFormat format, int frame_w, int frame_h, int plane)
const char ** av_vk_get_optional_device_extensions(int *count)
Returns an array of optional Vulkan device extensions that FFmpeg may use if enabled.
static int load_libvulkan(AVHWDeviceContext *ctx)
static int get_plane_buf(AVHWFramesContext *hwfc, FFVkBuffer **dst, AVFrame *swf, VkBufferImageCopy *region, int upload)
static void vulkan_frames_uninit(AVHWFramesContext *hwfc)
static int vulkan_device_has_rebar(AVHWDeviceContext *ctx)
static const VulkanOptExtension optional_instance_exts[]
static int check_layers(AVHWDeviceContext *ctx, AVDictionary *opts, const char *const **dst, uint32_t *num, enum FFVulkanDebugMode *debug_mode)
static int switch_layout_host(AVHWFramesContext *hwfc, FFVkExecPool *ectx, AVVkFrame *frame, enum PrepMode pmode)
static int vulkan_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame)
static int check_extensions(AVHWDeviceContext *ctx, int dev, AVDictionary *opts, const char *const **dst, uint32_t *num, enum FFVulkanDebugMode debug_mode)
const char ** av_vk_get_optional_instance_extensions(int *count)
Returns an array of optional Vulkan instance extensions that FFmpeg may use if enabled.
static int vkfmt_from_pixfmt2(AVHWDeviceContext *dev_ctx, enum AVPixelFormat p, VkImageTiling tiling, VkFormat fmts[AV_NUM_DATA_POINTERS], int *nb_images, VkImageAspectFlags *aspect, VkImageUsageFlags *supported_usage, int disable_multiplane, int need_storage)
static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts, enum FFVulkanDebugMode *debug_mode)
static const VulkanOptExtension optional_device_exts[]
@ PREP_MODE_EXTERNAL_EXPORT
@ PREP_MODE_EXTERNAL_IMPORT
static int vulkan_map_to(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src, int flags)
API-specific header for AV_HWDEVICE_TYPE_VULKAN.
@ AV_VK_FRAME_FLAG_DISABLE_MULTIPLANE
enum AVPixelFormat pixfmt
#define FF_DISABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
VkImageAspectFlags ff_vk_aspect_flag(AVFrame *f, int p)
Get the aspect flag for a plane from an image.
int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, FFVkExecPool *pool, int nb_contexts, int nb_queries, VkQueryType query_type, int query_64bit, const void *query_create_pnext)
Allocates/frees an execution pool.
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
int ff_vk_load_props(FFVulkanContext *s)
Loads props/mprops/driver_props.
const char * ff_vk_ret2str(VkResult res)
Converts Vulkan return values to strings.
int ff_vk_exec_add_dep_sw_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f)
void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar, VkPipelineStageFlags2 src_stage, VkPipelineStageFlags2 dst_stage, VkAccessFlagBits2 new_access, VkImageLayout new_layout, uint32_t new_qf)
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
int ff_vk_host_map_buffer(FFVulkanContext *s, FFVkBuffer **dst, uint8_t *src_data, VkDeviceSize size, const AVBufferRef *src_buf, VkBufferUsageFlags usage)
Maps a system RAM buffer into a Vulkan buffer.
void ff_vk_exec_add_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Execution dependency management.
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVRefStructPool **buf_pool, FFVkBuffer **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
int ff_vk_flush_buffer(FFVulkanContext *s, FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize mem_size, int flush)
Flush or invalidate a single buffer, with a given size and offset.
void ff_vk_exec_discard(FFVulkanContext *s, FFVkExecContext *e)
void ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, FFVkExecContext *e, VkSemaphore *sem, int nb, VkPipelineStageFlagBits2 stage, int wait)
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
void ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, FFVkExecContext *e, VkSemaphore sem, uint64_t val, VkPipelineStageFlagBits2 stage)
static const struct @257111027162314367033347246032313251342043035002 planes[]
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
#define AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_GBRPF32
#define AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_RGBF32
#define AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_RGBAF32
#define AV_PIX_FMT_RGBAF16
#define AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA420P16
#define AV_PIX_FMT_GBRAP32
#define AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_GBRAP14
#define AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GRAY32
#define AV_PIX_FMT_RGBA128
#define AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GBRAPF16
#define AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_BAYER_RGGB16
#define AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_X2RGB10
#define AV_PIX_FMT_GRAYF32
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
@ AV_PIX_FMT_NV24
planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
@ AV_PIX_FMT_DRM_PRIME
DRM-managed buffers exposed through PRIME buffer sharing.
@ AV_PIX_FMT_NV16
interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
#define AV_PIX_FMT_YUVA422P12
#define AV_PIX_FMT_X2BGR10
#define AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY14
#define AV_PIX_FMT_GBRPF16
#define AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_YUVA444P16
#define AV_PIX_FMT_YUVA422P16
#define AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_GBRAPF32
#define AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P10
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
#define FF_ARRAY_ELEMS(a)
A reference to a data buffer.
uint8_t * data
The data buffer.
This struct is allocated as AVHWDeviceContext.hwctx.
AVCUDADeviceContextInternal * internal
int fd
File descriptor of DRM device.
AVDRMObjectDescriptor objects[AV_DRM_MAX_PLANES]
Array of objects making up the frame.
int nb_layers
Number of layers in the frame.
int nb_objects
Number of DRM objects making up this frame.
AVDRMLayerDescriptor layers[AV_DRM_MAX_PLANES]
Array of layers in the frame.
AVDRMPlaneDescriptor planes[AV_DRM_MAX_PLANES]
Array of planes in this layer.
int nb_planes
Number of planes in the layer.
uint32_t format
Format of the layer (DRM_FORMAT_*).
int fd
DRM PRIME fd for the object.
size_t size
Total size of the object.
uint64_t format_modifier
Format modifier applied to the object (DRM_FORMAT_MOD_*).
ptrdiff_t pitch
Pitch (linesize) of this plane.
int object_index
Index of the object containing this plane in the objects array of the enclosing frame descriptor.
ptrdiff_t offset
Offset within that object of this plane.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
int max_width
The maximum size of frames in this hw_frames_ctx.
enum AVPixelFormat * valid_hw_formats
A list of possible values for format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
int min_width
The minimum size of frames in this hw_frames_ctx.
This struct describes a set or pool of "hardware" frames (i.e.
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
int width
The allocated dimensions of the frames in this pool.
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
AVBufferPool * pool
A pool from which the frames are allocated by av_hwframe_get_buffer().
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
AVRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
VAAPI connection details.
VADisplay display
The VADisplay handle, to be filled by the user.
pthread_mutex_t update_mutex
VkImageLayout layout[AV_NUM_DATA_POINTERS]
VkSemaphore sem[AV_NUM_DATA_POINTERS]
Synchronization timeline semaphores, one for each VkImage.
uint64_t sem_value[AV_NUM_DATA_POINTERS]
Up to date semaphore value at which each image becomes accessible.
struct AVVkFrameInternal * internal
Internal data.
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
VkPhysicalDevice phys_dev
Physical device.
AVVulkanDeviceQueueFamily qf[64]
Queue families used.
int nb_enabled_inst_extensions
const char *const * enabled_dev_extensions
Enabled device extensions.
const VkAllocationCallbacks * alloc
Custom memory allocator, else NULL.
VkDevice act_dev
Active device.
const char *const * enabled_inst_extensions
Enabled instance extensions.
VkInstance inst
Vulkan instance.
VkPhysicalDeviceFeatures2 device_features
This structure should be set to the set of features that present and enabled during device creation.
int nb_enabled_dev_extensions
VkDeviceQueueCreateFlags queue_flags
PFN_vkGetInstanceProcAddr get_proc_addr
Pointer to a vkGetInstanceProcAddr loading function.
VkVideoCodecOperationFlagBitsKHR video_caps
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
void * create_pnext
Extension data for image creation.
VkImageTiling tiling
Controls the tiling of allocated frames.
VkImageCreateFlags img_flags
Flags to set during image creation.
void * alloc_pnext[AV_NUM_DATA_POINTERS]
Extension data for memory allocation.
VkImageUsageFlagBits usage
Defines extra usage of output frames.
AVVkFrameFlags flags
A combination of AVVkFrameFlags.
void(* lock_frame)(struct AVHWFramesContext *fc, AVVkFrame *vkf)
Locks a frame, preventing other threads from changing frame properties.
int nb_layers
Number of layers each image will have.
void(* unlock_frame)(struct AVHWFramesContext *fc, AVVkFrame *vkf)
Similar to lock_frame(), unlocks a frame.
VkFormat format[AV_NUM_DATA_POINTERS]
Vulkan format for each image.
AVBufferPool * pool_internal
VkImageAspectFlags aspect
enum AVPixelFormat pixfmt
const VkFormat fallback[5]
void * priv
Hardware-specific private data associated with the mapping.
AVFrame * source
A reference to the original source of the mapping.
VkPhysicalDeviceVulkan11Features vulkan_1_1
VkPhysicalDeviceOpticalFlowFeaturesNV optical_flow
VkPhysicalDeviceVideoMaintenance1FeaturesKHR video_maintenance_1
VkPhysicalDeviceVulkan12Features vulkan_1_2
VkPhysicalDeviceCooperativeMatrixFeaturesKHR cooperative_matrix
VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR explicit_mem_layout
VkPhysicalDeviceVulkan13Features vulkan_1_3
VkPhysicalDeviceTimelineSemaphoreFeatures timeline_semaphore
VkPhysicalDeviceShaderSubgroupRotateFeaturesKHR subgroup_rotate
VkPhysicalDeviceShaderObjectFeaturesEXT shader_object
VkPhysicalDeviceFeatures2 device
VkPhysicalDeviceShaderAtomicFloatFeaturesEXT atomic_float
VkPhysicalDeviceHostImageCopyFeaturesEXT host_image_copy
AVVulkanDeviceQueueFamily * compute_qf
pthread_mutex_t ** qf_mutex
VkPhysicalDeviceMemoryProperties mprops
VulkanDeviceFeatures feats
AVVulkanDeviceContext p
The public AVVulkanDeviceContext.
VkPhysicalDeviceExternalMemoryHostPropertiesEXT hprops
VkPhysicalDeviceDriverProperties dprops
VkPhysicalDeviceProperties2 props
VkDebugUtilsMessengerEXT debug_ctx
VkExternalSemaphoreProperties ext_sem_props_opaque
AVVulkanDeviceQueueFamily * transfer_qf
int transfer_offset_align
uint8_t uuid[VK_UUID_SIZE]
VkImageDrmFormatModifierListCreateInfoEXT * modifier_info
VkDrmFormatModifierPropertiesEXT drm_format_modifier_properties[5]
FFVkExecPool compute_exec
FFVkExecPool download_exec
AVVulkanFramesContext p
The public AVVulkanFramesContext.
int export_requires_dedicated
#define av_malloc_array(a, b)
int av_uuid_parse(const char *in, AVUUID uu)
Parses a string representation of a UUID formatted according to IETF RFC 4122 into an AVUUID.
UUID parsing and serialization utilities.
static void lock_queue(void *priv, uint32_t qf, uint32_t qidx)
static void unlock_queue(void *priv, uint32_t qf, uint32_t qidx)
static int mod(int a, int b)
Modulo operation with only positive remainders.
#define FF_VK_DEFAULT_EXEC_CONTEXTS
#define FF_VK_STRUCT_EXT(CTX, BASE, STRUCT_P, EXT_FLAG, TYPE)
static const void * ff_vk_find_struct(const void *chain, VkStructureType stype)
static int ff_vk_count_images(AVVkFrame *f)
VkImageUsageFlags ff_vk_map_feats_to_usage(VkFormatFeatureFlagBits2 feats)
Map between usage and features.
static void ff_vk_link_struct(void *chain, const void *in)
#define FF_VK_EXT_VIDEO_ENCODE_AV1
#define FF_VK_EXT_EXPLICIT_MEM_LAYOUT
#define FF_VK_EXT_VIDEO_DECODE_H265
#define FF_VK_EXT_RELAXED_EXTENDED_INSTR
#define FF_VK_EXT_EXTERNAL_FD_SEM
#define FF_VK_EXT_PORTABILITY_SUBSET
#define FF_VK_EXT_VIDEO_MAINTENANCE_1
#define FF_VK_EXT_DRM_MODIFIER_FLAGS
#define FF_VK_EXT_SHADER_OBJECT
#define FF_VK_EXT_VIDEO_QUEUE
#define FF_VK_EXT_UNIFIED_IMAGE_LAYOUTS
uint64_t FFVulkanExtensions
#define FF_VK_EXT_COOP_MATRIX
#define FF_VK_EXT_INTERNAL_QUEUE_SYNC
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE
#define FF_VK_EXT_NO_FLAG
#define FF_VK_EXT_VIDEO_DECODE_AV1
#define FF_VK_EXT_OPTICAL_FLOW
#define FF_VK_EXT_EXTERNAL_DMABUF_MEMORY
#define FF_VK_EXT_MAINTENANCE_11
#define FF_VK_EXT_SUBGROUP_ROTATE
#define FF_VK_EXT_PUSH_DESCRIPTOR
#define FF_VK_EXT_MAXIMAL_RECONVERGENCE
#define FF_VK_EXT_DEVICE_DRM
#define FF_VK_EXT_VIDEO_DECODE_H264
#define FF_VK_EXT_VIDEO_ENCODE_H264
#define FF_VK_EXT_VIDEO_DECODE_QUEUE
#define FF_VK_EXT_LONG_VECTOR
#define FF_VK_EXT_VIDEO_DECODE_VP9
#define FF_VK_EXT_EXTERNAL_WIN32_SEM
#define FF_VK_EXT_MAINTENANCE_9
#define FF_VK_EXT_EXPECT_ASSUME
#define FF_VK_EXT_HOST_IMAGE_COPY
#define FF_VK_EXT_EXTERNAL_FD_MEMORY
#define FF_VK_EXT_ZERO_INITIALIZE
#define FF_VK_EXT_REPLICATED_COMPOSITES
#define FF_VK_EXT_VIDEO_ENCODE_H265
#define FF_VK_EXT_ATOMIC_FLOAT
#define FF_VK_EXT_EXTERNAL_HOST_MEMORY
#define FF_VK_EXT_EXTERNAL_WIN32_MEMORY
#define FF_VK_EXT_VIDEO_MAINTENANCE_2
static int ff_vk_load_functions(AVHWDeviceContext *ctx, FFVulkanFunctions *vk, uint64_t extensions_mask, int has_inst, int has_dev)
Function loader.