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_unified_image_layouts
111 VkPhysicalDeviceUnifiedImageLayoutsFeaturesKHR unified_layouts;
115#ifdef VK_KHR_video_maintenance2
116 VkPhysicalDeviceVideoMaintenance2FeaturesKHR video_maintenance_2;
118#ifdef VK_KHR_video_decode_vp9
119 VkPhysicalDeviceVideoDecodeVP9FeaturesKHR vp9_decode;
121#ifdef VK_KHR_video_encode_av1
122 VkPhysicalDeviceVideoEncodeAV1FeaturesKHR av1_encode;
129#ifdef VK_KHR_shader_relaxed_extended_instruction
130 VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR relaxed_extended_instruction;
133#ifdef VK_KHR_internally_synchronized_queues
134 VkPhysicalDeviceInternallySynchronizedQueuesFeaturesKHR internal_queue_sync;
155 VkPhysicalDeviceExternalMemoryHostPropertiesEXT
hprops;
243 feats->
device = (VkPhysicalDeviceFeatures2) {
244 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
248 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES);
250 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES);
252 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES);
255 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES);
257 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES_KHR);
259 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT);
261#ifdef VK_EXT_shader_long_vector
263 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_LONG_VECTOR_FEATURES_EXT);
266#ifdef VK_EXT_shader_replicated_composites
268 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_REPLICATED_COMPOSITES_FEATURES_EXT);
271#ifdef VK_EXT_zero_initialize_device_memory
273 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_DEVICE_MEMORY_FEATURES_EXT);
276#ifdef VK_KHR_shader_expect_assume
278 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES_KHR);
281#ifdef VK_KHR_shader_maximal_reconvergence
283 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MAXIMAL_RECONVERGENCE_FEATURES_KHR);
286#ifdef VK_KHR_maintenance9
288 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_9_FEATURES_KHR);
290#ifdef VK_KHR_unified_image_layouts
292 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFIED_IMAGE_LAYOUTS_FEATURES_KHR);
296 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR);
297#ifdef VK_KHR_video_maintenance2
299 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR);
301#ifdef VK_KHR_video_decode_vp9
303 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR);
305#ifdef VK_KHR_video_encode_av1
307 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR);
311 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);
313 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR);
315 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT);
317 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR);
319#ifdef VK_KHR_shader_relaxed_extended_instruction
321 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR);
324#ifdef VK_KHR_internally_synchronized_queues
326 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INTERNALLY_SYNCHRONIZED_QUEUES_FEATURES_KHR);
330 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV);
336#define COPY_VAL(VAL) \
338 dst->VAL = src->VAL; \
341 COPY_VAL(device.features.shaderImageGatherExtended);
342 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
343 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
344 COPY_VAL(device.features.fragmentStoresAndAtomics);
345 COPY_VAL(device.features.vertexPipelineStoresAndAtomics);
346 COPY_VAL(device.features.shaderInt64);
347 COPY_VAL(device.features.shaderInt16);
348 COPY_VAL(device.features.shaderFloat64);
349 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
350 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
352 COPY_VAL(vulkan_1_1.samplerYcbcrConversion);
353 COPY_VAL(vulkan_1_1.storagePushConstant16);
354 COPY_VAL(vulkan_1_1.storageBuffer16BitAccess);
355 COPY_VAL(vulkan_1_1.uniformAndStorageBuffer16BitAccess);
357 COPY_VAL(vulkan_1_2.timelineSemaphore);
358 COPY_VAL(vulkan_1_2.scalarBlockLayout);
359 COPY_VAL(vulkan_1_2.bufferDeviceAddress);
360 COPY_VAL(vulkan_1_2.hostQueryReset);
361 COPY_VAL(vulkan_1_2.storagePushConstant8);
363 COPY_VAL(vulkan_1_2.storageBuffer8BitAccess);
364 COPY_VAL(vulkan_1_2.uniformAndStorageBuffer8BitAccess);
366 COPY_VAL(vulkan_1_2.shaderBufferInt64Atomics);
367 COPY_VAL(vulkan_1_2.shaderSharedInt64Atomics);
368 COPY_VAL(vulkan_1_2.vulkanMemoryModel);
369 COPY_VAL(vulkan_1_2.vulkanMemoryModelDeviceScope);
370 COPY_VAL(vulkan_1_2.vulkanMemoryModelAvailabilityVisibilityChains);
371 COPY_VAL(vulkan_1_2.uniformBufferStandardLayout);
372 COPY_VAL(vulkan_1_2.runtimeDescriptorArray);
373 COPY_VAL(vulkan_1_2.shaderSubgroupExtendedTypes);
374 COPY_VAL(vulkan_1_2.shaderUniformBufferArrayNonUniformIndexing);
375 COPY_VAL(vulkan_1_2.shaderSampledImageArrayNonUniformIndexing);
376 COPY_VAL(vulkan_1_2.shaderStorageBufferArrayNonUniformIndexing);
377 COPY_VAL(vulkan_1_2.shaderStorageImageArrayNonUniformIndexing);
379 COPY_VAL(vulkan_1_3.dynamicRendering);
381 COPY_VAL(vulkan_1_3.synchronization2);
382 COPY_VAL(vulkan_1_3.computeFullSubgroups);
383 COPY_VAL(vulkan_1_3.subgroupSizeControl);
384 COPY_VAL(vulkan_1_3.shaderZeroInitializeWorkgroupMemory);
385 COPY_VAL(vulkan_1_3.dynamicRendering);
387 COPY_VAL(timeline_semaphore.timelineSemaphore);
388 COPY_VAL(subgroup_rotate.shaderSubgroupRotate);
389 COPY_VAL(host_image_copy.hostImageCopy);
391#ifdef VK_EXT_shader_long_vector
395#ifdef VK_EXT_shader_replicated_composites
396 COPY_VAL(replicated_composites.shaderReplicatedComposites);
399#ifdef VK_EXT_zero_initialize_device_memory
400 COPY_VAL(zero_initialize.zeroInitializeDeviceMemory);
403 COPY_VAL(video_maintenance_1.videoMaintenance1);
404#ifdef VK_KHR_video_maintenance2
405 COPY_VAL(video_maintenance_2.videoMaintenance2);
408#ifdef VK_KHR_video_decode_vp9
409 COPY_VAL(vp9_decode.videoDecodeVP9);
412#ifdef VK_KHR_video_encode_av1
413 COPY_VAL(av1_encode.videoEncodeAV1);
416 COPY_VAL(shader_object.shaderObject);
418 COPY_VAL(cooperative_matrix.cooperativeMatrix);
420 COPY_VAL(atomic_float.shaderBufferFloat32Atomics);
421 COPY_VAL(atomic_float.shaderBufferFloat32AtomicAdd);
423 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayout);
424 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayoutScalarBlockLayout);
425 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayout8BitAccess);
426 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayout16BitAccess);
428#ifdef VK_KHR_shader_relaxed_extended_instruction
429 COPY_VAL(relaxed_extended_instruction.shaderRelaxedExtendedInstruction);
432#ifdef VK_KHR_shader_expect_assume
433 COPY_VAL(expect_assume.shaderExpectAssume);
436#ifdef VK_KHR_shader_maximal_reconvergence
437 COPY_VAL(maximal_reconvergence.shaderMaximalReconvergence);
440#ifdef VK_KHR_maintenance9
441 COPY_VAL(maintenance_9.maintenance9);
443#ifdef VK_KHR_unified_image_layouts
444 COPY_VAL(unified_layouts.unifiedImageLayouts);
445 COPY_VAL(unified_layouts.unifiedImageLayoutsVideo);
448#ifdef VK_KHR_internally_synchronized_queues
449 COPY_VAL(internal_queue_sync.internallySynchronizedQueues);
457#define ASPECT_2PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT)
458#define ASPECT_3PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)
470 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_GRAY8, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8_UNORM } },
471 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
472 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY12, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
473 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY14, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
474 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
475 { VK_FORMAT_R32_UINT,
AV_PIX_FMT_GRAY32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_UINT } },
476 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GRAYF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_SFLOAT } },
479 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_BGRA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
480 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGBA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
481 { VK_FORMAT_R8G8B8_UNORM,
AV_PIX_FMT_RGB24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8_UNORM } },
482 { VK_FORMAT_B8G8R8_UNORM,
AV_PIX_FMT_BGR24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8_UNORM } },
483 { VK_FORMAT_R16G16B16_UNORM,
AV_PIX_FMT_RGB48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16_UNORM } },
484 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_RGBA64, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
485 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_BGR0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
486 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGB0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
487 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_X2RGB10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
488 { VK_FORMAT_A2B10G10R10_UNORM_PACK32,
AV_PIX_FMT_X2BGR10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2B10G10R10_UNORM_PACK32 } },
489 { VK_FORMAT_R32G32B32_SFLOAT,
AV_PIX_FMT_RGBF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_SFLOAT } },
490 { VK_FORMAT_R16G16B16A16_SFLOAT,
AV_PIX_FMT_RGBAF16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_SFLOAT } },
491 { VK_FORMAT_R32G32B32A32_SFLOAT,
AV_PIX_FMT_RGBAF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_SFLOAT } },
492 { VK_FORMAT_R32G32B32_UINT,
AV_PIX_FMT_RGB96, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_UINT } },
493 { VK_FORMAT_R32G32B32A32_UINT,
AV_PIX_FMT_RGBA128, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_UINT } },
496 { 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 } },
497 { 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 } },
498 { 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 } },
499 { 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 } },
500 { 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 } },
501 { 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 } },
502 { 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 } },
505 { 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 } },
506 { 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 } },
507 { 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 } },
508 { 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 } },
509 { 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 } },
510 { 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 } },
511 { 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 } },
512 { 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 } },
519 { 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 } },
520 { 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 } },
525 { 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 } },
526 { 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 } },
531 { 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 } },
532 { 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 } },
550 { VK_FORMAT_G8B8G8R8_422_UNORM,
AV_PIX_FMT_YUYV422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
551 { VK_FORMAT_B8G8R8G8_422_UNORM,
AV_PIX_FMT_UYVY422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
552 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
AV_PIX_FMT_Y210, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
553 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
AV_PIX_FMT_Y212, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
554 { VK_FORMAT_G16B16G16R16_422_UNORM,
AV_PIX_FMT_Y216, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
557 { 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 } },
558 { 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 } },
559 { 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 } },
562 { 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 } },
563 { 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 } },
564 { 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 } },
565 { 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 } },
568 { 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 } },
569 { 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 } },
570 { 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 } },
571 { 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 } },
574 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_XV30, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
575 { VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
AV_PIX_FMT_XV36, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
576 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_XV48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
597 VkImageTiling tiling,
600 VkImageAspectFlags *
aspect,
601 VkImageUsageFlags *supported_usage,
602 int disable_multiplane,
int need_storage)
608 const VkFormatFeatureFlagBits2 basic_flags = VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
609 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
610 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
614 VkFormatProperties3 fprops = {
615 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3,
617 VkFormatProperties2 prop = {
618 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
621 VkFormatFeatureFlagBits2 feats_primary, feats_secondary;
622 int basics_primary = 0, basics_secondary = 0;
623 int storage_primary = 0, storage_secondary = 0;
625 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
629 feats_primary = tiling == VK_IMAGE_TILING_LINEAR ?
630 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
631 basics_primary = (feats_primary & basic_flags) == basic_flags;
632 storage_primary = !!(feats_primary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
635 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
638 feats_secondary = tiling == VK_IMAGE_TILING_LINEAR ?
639 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
640 basics_secondary = (feats_secondary & basic_flags) == basic_flags;
641 storage_secondary = !!(feats_secondary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
643 basics_secondary = basics_primary;
644 storage_secondary = storage_primary;
647 if (basics_primary &&
649 (!need_storage || (need_storage && (storage_primary | storage_secondary)))) {
664 ((need_storage && (storage_primary | storage_secondary)) ?
665 VK_IMAGE_USAGE_STORAGE_BIT : 0);
667 }
else if (basics_secondary &&
668 (!need_storage || (need_storage && storage_secondary))) {
689#if CONFIG_VULKAN_STATIC
690VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance,
699#if CONFIG_VULKAN_STATIC
702 static const char *lib_names[] = {
705#elif defined(__APPLE__)
716 p->libvulkan = dlopen(lib_names[
i], RTLD_NOW | RTLD_LOCAL);
726 hwctx->
get_proc_addr = (PFN_vkGetInstanceProcAddr)dlsym(p->libvulkan,
"vkGetInstanceProcAddr");
755#ifdef VK_KHR_shader_relaxed_extended_instruction
758#ifdef VK_EXT_shader_long_vector
761#ifdef VK_EXT_shader_replicated_composites
764#ifdef VK_EXT_zero_initialize_device_memory
767#ifdef VK_KHR_shader_expect_assume
770#ifdef VK_KHR_shader_maximal_reconvergence
773#ifdef VK_KHR_maintenance9
776#ifdef VK_KHR_unified_image_layouts
780#ifdef VK_KHR_video_maintenance2
783#ifdef VK_KHR_internally_synchronized_queues
807#ifdef VK_KHR_video_decode_vp9
810#ifdef VK_KHR_video_encode_av1
846 VkDebugUtilsMessageTypeFlagsEXT messageType,
847 const VkDebugUtilsMessengerCallbackDataEXT *
data,
854 switch (
data->messageIdNumber) {
863 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: l =
AV_LOG_VERBOSE;
break;
864 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: l =
AV_LOG_INFO;
break;
865 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: l =
AV_LOG_WARNING;
break;
866 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: l =
AV_LOG_ERROR;
break;
871 for (
int i = 0;
i <
data->cmdBufLabelCount;
i++)
877#define ADD_VAL_TO_LIST(list, count, val) \
879 list = av_realloc_array(list, ++count, sizeof(*list)); \
881 err = AVERROR(ENOMEM); \
884 list[count - 1] = av_strdup(val); \
885 if (!list[count - 1]) { \
886 err = AVERROR(ENOMEM); \
891#define RELEASE_PROPS(props, count) \
893 for (int i = 0; i < count; i++) \
894 av_free((void *)((props)[i])); \
895 av_free((void *)props); \
901 VkDeviceSize max_vram = 0, max_visible_vram = 0;
905 for (
int i = 0;
i < p->mprops.memoryTypeCount;
i++) {
906 const VkMemoryType
type = p->mprops.memoryTypes[
i];
907 const VkMemoryHeap heap = p->mprops.memoryHeaps[
type.heapIndex];
908 if (!(
type.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
910 max_vram =
FFMAX(max_vram, heap.size);
911 if (
type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
912 max_visible_vram =
FFMAX(max_visible_vram, heap.size);
915 return max_vram - max_visible_vram < 1024;
931 const char *
const **
dst, uint32_t *num,
935 const char **extension_names =
NULL;
939 int err = 0, found, extensions_found = 0;
942 int optional_exts_num;
943 uint32_t sup_ext_count;
944 char *user_exts_str =
NULL;
946 VkExtensionProperties *sup_ext;
956 if (!user_exts_str) {
961 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count,
NULL);
962 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
965 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count, sup_ext);
973 if (!user_exts_str) {
978 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
979 &sup_ext_count,
NULL);
980 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
983 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
984 &sup_ext_count, sup_ext);
987 for (
int i = 0;
i < optional_exts_num;
i++) {
988 tstr = optional_exts[
i].
name;
992 if (!strcmp(tstr, VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME) &&
1000 (!strcmp(tstr, VK_EXT_SHADER_OBJECT_EXTENSION_NAME))) {
1004 for (
int j = 0; j < sup_ext_count; j++) {
1005 if (!strcmp(tstr, sup_ext[j].extensionName)) {
1014 p->vkctx.extensions |= optional_exts[
i].
flag;
1022 tstr = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
1024 for (
int j = 0; j < sup_ext_count; j++) {
1025 if (!strcmp(tstr, sup_ext[j].extensionName)) {
1041#ifdef VK_KHR_shader_relaxed_extended_instruction
1043 tstr = VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME;
1045 for (
int j = 0; j < sup_ext_count; j++) {
1046 if (!strcmp(tstr, sup_ext[j].extensionName)) {
1060 if (user_exts_str) {
1061 char *save, *token =
av_strtok(user_exts_str,
"+", &save);
1064 for (
int j = 0; j < sup_ext_count; j++) {
1065 if (!strcmp(token, sup_ext[j].extensionName)) {
1081 *
dst = extension_names;
1082 *num = extensions_found;
1096 const char *
const **
dst, uint32_t *num,
1103 static const char layer_standard_validation[] = {
"VK_LAYER_KHRONOS_validation" };
1104 int layer_standard_validation_found = 0;
1106 uint32_t sup_layer_count;
1107 VkLayerProperties *sup_layers;
1110 char *user_layers_str =
NULL;
1113 const char **enabled_layers =
NULL;
1114 uint32_t enabled_layers_count = 0;
1122 vk->EnumerateInstanceLayerProperties(&sup_layer_count,
NULL);
1123 sup_layers =
av_malloc_array(sup_layer_count,
sizeof(VkLayerProperties));
1126 vk->EnumerateInstanceLayerProperties(&sup_layer_count, sup_layers);
1129 for (
int i = 0;
i < sup_layer_count;
i++)
1133 if (!debug_opt && !user_layers)
1138 if (!strcmp(debug_opt->
value,
"printf")) {
1140 }
else if (!strcmp(debug_opt->
value,
"validate")) {
1142 }
else if (!strcmp(debug_opt->
value,
"practices")) {
1145 char *end_ptr =
NULL;
1146 int idx = strtol(debug_opt->
value, &end_ptr, 10);
1147 if (end_ptr == debug_opt->
value || end_ptr[0] !=
'\0' ||
1162 for (
int i = 0;
i < sup_layer_count;
i++) {
1163 if (!strcmp(layer_standard_validation, sup_layers[
i].layerName)) {
1165 layer_standard_validation);
1166 ADD_VAL_TO_LIST(enabled_layers, enabled_layers_count, layer_standard_validation);
1168 layer_standard_validation_found = 1;
1172 if (!layer_standard_validation_found) {
1174 "Validation Layer \"%s\" not supported\n", layer_standard_validation);
1185 if (!user_layers_str) {
1190 token =
av_strtok(user_layers_str,
"+", &save);
1195 if (!strcmp(layer_standard_validation, token) && layer_standard_validation_found) {
1201 for (
int j = 0; j < sup_layer_count; j++) {
1202 if (!strcmp(token, sup_layers[j].layerName)) {
1213 if (!strcmp(layer_standard_validation, token))
1217 "Layer \"%s\" not supported\n", token);
1234 *
dst = enabled_layers;
1235 *num = enabled_layers_count;
1250 VkApplicationInfo application_info = {
1251 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
1252 .pApplicationName =
"ffmpeg",
1256 .pEngineName =
"libavutil",
1257 .apiVersion = VK_API_VERSION_1_3,
1262 VkValidationFeaturesEXT validation_features = {
1263 .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
1265 VkInstanceCreateInfo inst_props = {
1266 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
1267 .pApplicationInfo = &application_info,
1283 &inst_props.enabledLayerCount, debug_mode);
1289 &inst_props.enabledExtensionCount, *debug_mode);
1297 static const VkValidationFeatureEnableEXT feat_list_validate[] = {
1298 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1299 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1300 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
1302 validation_features.pEnabledValidationFeatures = feat_list_validate;
1303 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_validate);
1304 inst_props.pNext = &validation_features;
1306 static const VkValidationFeatureEnableEXT feat_list_debug[] = {
1307 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1308 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1309 VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT,
1311 validation_features.pEnabledValidationFeatures = feat_list_debug;
1312 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_debug);
1313 inst_props.pNext = &validation_features;
1315 static const VkValidationFeatureEnableEXT feat_list_practices[] = {
1316 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1317 VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT,
1319 validation_features.pEnabledValidationFeatures = feat_list_practices;
1320 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_practices);
1321 inst_props.pNext = &validation_features;
1325 for (
int i = 0;
i < inst_props.enabledExtensionCount;
i++) {
1326 if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
1327 inst_props.ppEnabledExtensionNames[
i])) {
1328 inst_props.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
1335 ret = vk->CreateInstance(&inst_props, hwctx->
alloc, &hwctx->
inst);
1338 if (ret != VK_SUCCESS) {
1355 VkDebugUtilsMessengerCreateInfoEXT dbg = {
1356 .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
1357 .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
1358 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
1359 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
1360 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
1361 .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
1362 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
1363 VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
1368 vk->CreateDebugUtilsMessengerEXT(hwctx->
inst, &dbg,
1369 hwctx->
alloc, &p->debug_ctx);
1375 RELEASE_PROPS(inst_props.ppEnabledLayerNames, inst_props.enabledLayerCount);
1394 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
return "integrated";
1395 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
return "discrete";
1396 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
return "virtual";
1397 case VK_PHYSICAL_DEVICE_TYPE_CPU:
return "software";
1398 default:
return "unknown";
1405 int err = 0, choice = -1;
1411 VkPhysicalDevice *devices =
NULL;
1412 VkPhysicalDeviceIDProperties *idp =
NULL;
1413 VkPhysicalDeviceProperties2 *prop =
NULL;
1414 VkPhysicalDeviceDriverProperties *driver_prop =
NULL;
1415 VkPhysicalDeviceDrmPropertiesEXT *drm_prop =
NULL;
1417 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num,
NULL);
1418 if (ret != VK_SUCCESS || !num) {
1427 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num, devices);
1428 if (ret != VK_SUCCESS) {
1447 driver_prop =
av_calloc(num,
sizeof(*driver_prop));
1454 drm_prop =
av_calloc(num,
sizeof(*drm_prop));
1462 for (
int i = 0;
i < num;
i++) {
1464 drm_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT;
1465 driver_prop[
i].pNext = &drm_prop[
i];
1467 driver_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
1468 idp[
i].pNext = &driver_prop[
i];
1469 idp[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
1470 prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1471 prop[
i].pNext = &idp[
i];
1473 vk->GetPhysicalDeviceProperties2(devices[
i], &prop[
i]);
1475 prop[
i].properties.deviceName,
1477 prop[
i].properties.deviceID);
1481 for (
int i = 0;
i < num;
i++) {
1482 if (!memcmp(idp[
i].deviceUUID, select->
uuid, VK_UUID_SIZE)) {
1491 for (
int i = 0;
i < num;
i++) {
1492 if ((select->
drm_major == drm_prop[
i].primaryMajor &&
1493 select->
drm_minor == drm_prop[
i].primaryMinor) ||
1494 (select->
drm_major == drm_prop[
i].renderMajor &&
1495 select->
drm_minor == drm_prop[
i].renderMinor)) {
1504 }
else if (select->
name) {
1506 for (
int i = 0;
i < num;
i++) {
1507 if (strstr(prop[
i].properties.deviceName, select->
name)) {
1518 for (
int i = 0;
i < num;
i++) {
1519 if (select->
pci_device == prop[
i].properties.deviceID) {
1530 for (
int i = 0;
i < num;
i++) {
1531 if (select->
vendor_id == prop[
i].properties.vendorID) {
1541 if (select->
index < num) {
1542 choice = select->
index;
1554 choice, prop[choice].properties.deviceName,
1556 prop[choice].properties.deviceID);
1558 p->props = prop[choice];
1559 p->props.pNext =
NULL;
1560 p->dprops = driver_prop[choice];
1561 p->dprops.pNext =
NULL;
1575 VkQueueFlagBits
flags)
1578 uint32_t min_score = UINT32_MAX;
1580 for (
int i = 0;
i < num_qf;
i++) {
1581 VkQueueFlagBits qflags = qf[
i].queueFamilyProperties.queueFlags;
1584 if ((
flags & VK_QUEUE_TRANSFER_BIT) &&
1585 (qflags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)))
1586 qflags |= VK_QUEUE_TRANSFER_BIT;
1588 if (qflags &
flags) {
1589 uint32_t score =
av_popcount(qflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1590 if (score < min_score) {
1598 qf[
index].queueFamilyProperties.timestampValidBits++;
1604 VkQueueFamilyVideoPropertiesKHR *qf_vid, uint32_t num_qf,
1605 VkVideoCodecOperationFlagsKHR
flags)
1608 uint32_t min_score = UINT32_MAX;
1610 for (
int i = 0;
i < num_qf;
i++) {
1611 const VkQueueFlags qflags = qf[
i].queueFamilyProperties.queueFlags;
1612 const VkVideoCodecOperationFlagsKHR vflags = qf_vid[
i].videoCodecOperations;
1614 if (!(qflags & (VK_QUEUE_VIDEO_ENCODE_BIT_KHR | VK_QUEUE_VIDEO_DECODE_BIT_KHR)))
1617 if (vflags &
flags) {
1618 uint32_t score =
av_popcount(vflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1619 if (score < min_score) {
1627 qf[
index].queueFamilyProperties.timestampValidBits++;
1639 VkQueueFamilyProperties2 *qf =
NULL;
1640 VkQueueFamilyVideoPropertiesKHR *qf_vid =
NULL;
1643 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &num,
NULL);
1654 qf_vid =
av_malloc_array(num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
1658 for (uint32_t
i = 0;
i < num;
i++) {
1659 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1660 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1662 qf[
i] = (VkQueueFamilyProperties2) {
1663 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
1669 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &num, qf);
1672 for (
int i = 0;
i < num;
i++) {
1674 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_GRAPHICS_BIT) ?
" graphics" :
"",
1675 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_COMPUTE_BIT) ?
" compute" :
"",
1676 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_TRANSFER_BIT) ?
" transfer" :
"",
1677 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ?
" encode" :
"",
1678 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_DECODE_BIT_KHR) ?
" decode" :
"",
1679 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_SPARSE_BINDING_BIT) ?
" sparse" :
"",
1680 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_OPTICAL_FLOW_BIT_NV) ?
" optical_flow" :
"",
1681 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_PROTECTED_BIT) ?
" protected" :
"",
1682 qf[
i].queueFamilyProperties.queueCount);
1686 qf[
i].queueFamilyProperties.timestampValidBits = 0;
1691#ifdef VK_KHR_internally_synchronized_queues
1693 hwctx->
queue_flags |= VK_DEVICE_QUEUE_CREATE_INTERNALLY_SYNCHRONIZED_BIT_KHR;
1697#define PICK_QF(type, vid_op) \
1703 idx = pick_video_queue_family(qf, qf_vid, num, vid_op); \
1705 idx = pick_queue_family(qf, num, type); \
1710 for (i = 0; i < hwctx->nb_qf; i++) { \
1711 if (hwctx->qf[i].idx == idx) { \
1712 hwctx->qf[i].flags |= type; \
1713 hwctx->qf[i].video_caps |= vid_op; \
1717 if (i == hwctx->nb_qf) { \
1718 hwctx->qf[i].idx = idx; \
1719 hwctx->qf[i].num = qf[idx].queueFamilyProperties.queueCount; \
1720 if (p->limit_queues || \
1721 p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) { \
1722 int max = p->limit_queues; \
1723 if (type == VK_QUEUE_GRAPHICS_BIT) \
1724 hwctx->qf[i].num = FFMIN(hwctx->qf[i].num, \
1727 hwctx->qf[i].num = FFMIN(hwctx->qf[i].num, max); \
1729 hwctx->qf[i].flags = type; \
1730 hwctx->qf[i].video_caps = vid_op; \
1735 PICK_QF(VK_QUEUE_GRAPHICS_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1736 PICK_QF(VK_QUEUE_COMPUTE_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1737 PICK_QF(VK_QUEUE_TRANSFER_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1739 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR);
1740 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR);
1742 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR);
1743 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR);
1745#ifdef VK_KHR_video_decode_vp9
1746 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR);
1749#ifdef VK_KHR_video_encode_av1
1750 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR);
1752 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR);
1755 PICK_QF(VK_QUEUE_OPTICAL_FLOW_BIT_NV, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1763 sizeof(VkDeviceQueueCreateInfo));
1764 if (!cd->pQueueCreateInfos)
1767 for (uint32_t
i = 0;
i < hwctx->
nb_qf;
i++) {
1770 VkDeviceQueueCreateInfo *pc;
1771 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++) {
1772 if (hwctx->
qf[
i].
idx == cd->pQueueCreateInfos[j].queueFamilyIndex) {
1782 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++)
1783 av_free((
void *)cd->pQueueCreateInfos[
i].pQueuePriorities);
1784 av_free((
void *)cd->pQueueCreateInfos);
1788 for (uint32_t j = 0; j < hwctx->
qf[
i].
num; j++)
1791 pc = (VkDeviceQueueCreateInfo *)cd->pQueueCreateInfos;
1792 pc[cd->queueCreateInfoCount++] = (VkDeviceQueueCreateInfo) {
1793 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1795 .queueFamilyIndex = hwctx->
qf[
i].
idx,
1796 .queueCount = hwctx->
qf[
i].
num,
1819 vk->DestroyDebugUtilsMessengerEXT(hwctx->
inst, p->debug_ctx,
1823 vk->DestroyInstance(hwctx->
inst, hwctx->
alloc);
1826 dlclose(p->libvulkan);
1837 for (uint32_t
i = 0;
i < p->nb_tot_qfs;
i++) {
1849 int disable_multiplane,
1860 VkDeviceCreateInfo dev_info = {
1861 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1873 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->mprops);
1877 &dev_info.enabledExtensionCount, debug_mode))) {
1878 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1879 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1880 av_free((
void *)dev_info.pQueueCreateInfos);
1886 vk->GetPhysicalDeviceFeatures2(hwctx->
phys_dev, &supported_feats.
device);
1891 dev_info.pNext = p->feats.device.pNext;
1892 dev_info.pEnabledFeatures = &p->feats.device.features;
1897 p->limit_queues = strtol(opt_d->
value,
NULL, 10);
1904 ret = vk->CreateDevice(hwctx->
phys_dev, &dev_info, hwctx->
alloc,
1907 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1908 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1909 av_free((
void *)dev_info.pQueueCreateInfos);
1911 if (ret != VK_SUCCESS) {
1914 for (
int i = 0;
i < dev_info.enabledExtensionCount;
i++)
1915 av_free((
void *)dev_info.ppEnabledExtensionNames[
i]);
1916 av_free((
void *)dev_info.ppEnabledExtensionNames);
1924 p->use_linear_images = strtol(opt_d->
value,
NULL, 10);
1927 p->disable_multiplane = disable_multiplane;
1928 if (!p->disable_multiplane) {
1931 p->disable_multiplane = strtol(opt_d->
value,
NULL, 10);
1935 p->avoid_host_import = p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY;
1938 p->avoid_host_import = strtol(opt_d->
value,
NULL, 10);
1975 VkQueueFamilyProperties2 *qf;
1976 VkQueueFamilyVideoPropertiesKHR *qf_vid;
1977 VkPhysicalDeviceExternalSemaphoreInfo ext_sem_props_info;
1996 p->props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1997 p->props.pNext = &p->hprops;
1998 p->hprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;
1999 p->hprops.pNext = &p->dprops;
2000 p->dprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
2002 vk->GetPhysicalDeviceProperties2(hwctx->
phys_dev, &p->props);
2004 p->props.properties.deviceName);
2007 p->props.properties.limits.optimalBufferCopyRowPitchAlignment);
2009 p->props.properties.limits.minMemoryMapAlignment);
2011 p->props.properties.limits.nonCoherentAtomSize);
2014 p->hprops.minImportedHostPointerAlignment);
2016 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &qf_num,
NULL);
2022 ext_sem_props_info = (VkPhysicalDeviceExternalSemaphoreInfo) {
2023 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
2027 ext_sem_props_info.handleType =
2029 IsWindows8OrGreater()
2030 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2031 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
2033 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
2035 p->ext_sem_props_opaque.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES;
2036 vk->GetPhysicalDeviceExternalSemaphoreProperties(hwctx->
phys_dev,
2037 &ext_sem_props_info,
2038 &p->ext_sem_props_opaque);
2044 qf_vid =
av_malloc_array(qf_num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
2050 for (uint32_t
i = 0;
i < qf_num;
i++) {
2051 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
2052 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
2054 qf[
i] = (VkQueueFamilyProperties2) {
2055 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
2060 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &qf_num, qf);
2062 p->nb_tot_qfs = qf_num;
2065 p->qf_mutex =
av_calloc(qf_num,
sizeof(*p->qf_mutex));
2071 for (uint32_t
i = 0;
i < qf_num;
i++) {
2072 p->qf_mutex[
i] =
av_calloc(qf[
i].queueFamilyProperties.queueCount,
2073 sizeof(**p->qf_mutex));
2074 if (!p->qf_mutex[
i]) {
2078 for (uint32_t j = 0; j < qf[
i].queueFamilyProperties.queueCount; j++) {
2090 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
2092 hwctx->
qf[
i].
flags & (VK_QUEUE_VIDEO_DECODE_BIT_KHR |
2093 VK_QUEUE_VIDEO_ENCODE_BIT_KHR)) {
2100 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
2104 for (
int j = (
i - 1); j >= 0; j--) {
2111 p->img_qfs[p->nb_img_qfs++] = hwctx->
qf[
i].
idx;
2114#if FF_API_VULKAN_SYNC_QUEUES
2116 if (!hwctx->lock_queue)
2118 if (!hwctx->unlock_queue)
2124 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->mprops);
2126 p->vkctx.device =
ctx;
2127 p->vkctx.hwctx = hwctx;
2130 p->compute_qf =
ff_vk_qf_find(&p->vkctx, VK_QUEUE_COMPUTE_BIT, 0);
2131 p->transfer_qf =
ff_vk_qf_find(&p->vkctx, VK_QUEUE_TRANSFER_BIT, 0);
2134 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->mprops);
2146 if (device && device[0]) {
2152 dev_select.
index = strtol(device, &end, 10);
2153 if (end == device || *end) {
2154 dev_select.
index = 0;
2155 dev_select.
name = device;
2172 switch(src_ctx->
type) {
2176 VADisplay dpy = src_hwctx->
display;
2177#if VA_CHECK_VERSION(1, 15, 0)
2179 VADisplayAttribute attr = {
2180 .type = VADisplayPCIID,
2185#if VA_CHECK_VERSION(1, 15, 0)
2186 vas = vaGetDisplayAttributes(dpy, &attr, 1);
2187 if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED)
2188 dev_select.pci_device = (attr.value & 0xFFFF);
2191 if (!dev_select.pci_device) {
2192 vendor = vaQueryVendorString(dpy);
2198 if (strstr(vendor,
"AMD"))
2199 dev_select.vendor_id = 0x1002;
2208 struct stat drm_node_info;
2209 drmDevice *drm_dev_info;
2212 err = fstat(src_hwctx->
fd, &drm_node_info);
2219 dev_select.drm_major = major(drm_node_info.st_dev);
2220 dev_select.drm_minor = minor(drm_node_info.st_dev);
2221 dev_select.has_drm = 1;
2223 err = drmGetDevice(src_hwctx->
fd, &drm_dev_info);
2230 if (drm_dev_info->bustype == DRM_BUS_PCI)
2231 dev_select.pci_device = drm_dev_info->deviceinfo.pci->device_id;
2233 drmFreeDevice(&drm_dev_info);
2243 CudaFunctions *cu = cu_internal->
cuda_dl;
2245 int ret =
CHECK_CU(cu->cuDeviceGetUuid((CUuuid *)&dev_select.uuid,
2252 dev_select.has_uuid = 1;
2267 const void *hwconfig,
2275 p->use_linear_images ? VK_IMAGE_TILING_LINEAR :
2276 VK_IMAGE_TILING_OPTIMAL,
2288 p->use_linear_images ? VK_IMAGE_TILING_LINEAR :
2289 VK_IMAGE_TILING_OPTIMAL,
2303 constraints->
max_width = p->props.properties.limits.maxImageDimension2D;
2304 constraints->
max_height = p->props.properties.limits.maxImageDimension2D;
2317 VkMemoryPropertyFlagBits req_flags,
const void *alloc_extension,
2318 VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
2325 VkMemoryAllocateInfo alloc_info = {
2326 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2327 .pNext = alloc_extension,
2328 .allocationSize = req->size,
2333 for (
int i = 0;
i < p->mprops.memoryTypeCount;
i++) {
2334 const VkMemoryType *
type = &p->mprops.memoryTypes[
i];
2337 if (!(req->memoryTypeBits & (1 <<
i)))
2341 if ((
type->propertyFlags & req_flags) != req_flags)
2345 if (req->size > p->mprops.memoryHeaps[
type->heapIndex].size)
2359 alloc_info.memoryTypeIndex =
index;
2361 ret = vk->AllocateMemory(dev_hwctx->
act_dev, &alloc_info,
2362 dev_hwctx->
alloc, mem);
2363 if (ret != VK_SUCCESS) {
2369 *mem_flags |= p->mprops.memoryTypes[
index].propertyFlags;
2383 if (internal->cuda_fc_ref) {
2389 CudaFunctions *cu = cu_internal->
cuda_dl;
2392 if (internal->cu_sem[
i])
2393 CHECK_CU(cu->cuDestroyExternalSemaphore(internal->cu_sem[
i]));
2394 if (internal->cu_mma[
i])
2395 CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[
i]));
2396 if (internal->ext_mem[
i])
2397 CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[
i]));
2399 if (internal->ext_sem_handle[
i])
2400 CloseHandle(internal->ext_sem_handle[
i]);
2401 if (internal->ext_mem_handle[
i])
2402 CloseHandle(internal->ext_mem_handle[
i]);
2410 if (internal->drm_sync_sem != VK_NULL_HANDLE)
2411 p->vkctx.vkfn.DestroySemaphore(p->p.act_dev, internal->drm_sync_sem,
2431 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
2433 .pSemaphores =
f->sem,
2434 .pValues =
f->sem_value,
2435 .semaphoreCount = nb_sems,
2443 for (
int i = 0;
i < nb_images;
i++) {
2458 void *alloc_pnext,
size_t alloc_pnext_stride)
2460 int img_cnt = 0, err;
2468 while (
f->img[img_cnt]) {
2470 VkImageMemoryRequirementsInfo2 req_desc = {
2471 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
2472 .image =
f->img[img_cnt],
2474 VkMemoryDedicatedAllocateInfo ded_alloc = {
2475 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
2476 .pNext = (
void *)(((uint8_t *)alloc_pnext) + img_cnt*alloc_pnext_stride),
2478 VkMemoryDedicatedRequirements ded_req = {
2479 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
2481 VkMemoryRequirements2 req = {
2482 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
2486 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req);
2489 "plane %d: driver reports prefersDedicatedAllocation=%i requiresDedicatedAllocation=%i\n",
2490 img_cnt, ded_req.prefersDedicatedAllocation, ded_req.requiresDedicatedAllocation);
2492 if (
f->tiling == VK_IMAGE_TILING_LINEAR)
2493 req.memoryRequirements.size =
FFALIGN(req.memoryRequirements.size,
2494 p->props.properties.limits.minMemoryMapAlignment);
2497 use_ded_mem = ded_req.prefersDedicatedAllocation |
2498 ded_req.requiresDedicatedAllocation;
2502 ded_alloc.image =
f->img[img_cnt];
2506 f->tiling == VK_IMAGE_TILING_LINEAR ?
2507 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
2508 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2509 use_ded_mem ? &ded_alloc : (
void *)ded_alloc.pNext,
2510 &
f->flags, &
f->mem[img_cnt])))
2513 f->size[img_cnt] = req.memoryRequirements.size;
2514 bind_info[img_cnt].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
2515 bind_info[img_cnt].image =
f->img[img_cnt];
2516 bind_info[img_cnt].memory =
f->mem[img_cnt];
2522 ret = vk->BindImageMemory2(hwctx->
act_dev, img_cnt, bind_info);
2523 if (ret != VK_SUCCESS) {
2543 VkAccessFlags2 *new_access)
2547 *new_layout = VK_IMAGE_LAYOUT_GENERAL;
2548 *new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2551 *new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
2552 *new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2555 *new_layout = VK_IMAGE_LAYOUT_GENERAL;
2556 *new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2559 *new_layout = VK_IMAGE_LAYOUT_GENERAL;
2560 *new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2563 *new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR;
2564 *new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2567 *new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR;
2568 *new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2571 *new_layout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR;
2572 *new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2586 VkImageLayout new_layout;
2587 VkAccessFlags2 new_access;
2590 uint32_t dst_qf = p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED : p->img_qfs[0];
2591 VkPipelineStageFlagBits2 src_stage = VK_PIPELINE_STAGE_2_NONE;
2593 dst_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR;
2594 src_stage = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
2601 .data = (uint8_t *)hwfc,
2604 .data[0] = (uint8_t *)
frame,
2605 .hw_frames_ctx = &tmp_ref,
2608 VkCommandBuffer cmd_buf;
2610 cmd_buf = exec->
buf;
2616 VK_PIPELINE_STAGE_2_NONE,
2617 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
2623 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
2624 new_access, new_layout, dst_qf);
2626 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
2627 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
2628 .pImageMemoryBarriers = img_bar,
2629 .imageMemoryBarrierCount = nb_img_bar,
2651 VkImageLayout new_layout;
2652 VkAccessFlags2 new_access;
2656 for (
i = 0;
i < p->vkctx.host_image_props.copyDstLayoutCount;
i++) {
2657 if (p->vkctx.host_image_props.pCopyDstLayouts[
i] == new_layout)
2660 if (
i == p->vkctx.host_image_props.copyDstLayoutCount)
2663 for (
i = 0;
i < nb_images;
i++) {
2664 layout_change[
i] = (VkHostImageLayoutTransitionInfoEXT) {
2665 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT,
2667 .oldLayout =
frame->layout[
i],
2668 .newLayout = new_layout,
2669 .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
2670 .subresourceRange.layerCount = 1,
2671 .subresourceRange.levelCount = 1,
2673 frame->layout[
i] = new_layout;
2676 ret = vk->TransitionImageLayoutEXT(p->vkctx.hwctx->act_dev,
2677 nb_images, layout_change);
2678 if (ret != VK_SUCCESS) {
2692 if (hwfc_vk->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT &&
2704 int frame_w,
int frame_h,
int plane)
2721 VkImageTiling tiling, VkImageUsageFlagBits
usage,
2722 VkImageCreateFlags
flags,
int nb_layers,
2734 VkSemaphoreTypeCreateInfo sem_type_info = {
2735 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2736 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2739 VkSemaphoreCreateInfo sem_spawn = {
2740 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2741 .pNext = &sem_type_info,
2744 VkExportSemaphoreCreateInfo ext_sem_info_opaque = {
2745 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
2747 .handleTypes = IsWindows8OrGreater()
2748 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2749 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
2751 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
2756 if (p->ext_sem_props_opaque.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) {
2770 for (
int i = 0; (hwfc_vk->
format[
i] != VK_FORMAT_UNDEFINED);
i++) {
2771 VkImageCreateInfo create_info = {
2772 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2773 .pNext = create_pnext,
2774 .imageType = VK_IMAGE_TYPE_2D,
2778 .arrayLayers = nb_layers,
2781 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2783 .samples = VK_SAMPLE_COUNT_1_BIT,
2784 .pQueueFamilyIndices = p->img_qfs,
2785 .queueFamilyIndexCount = p->nb_img_qfs,
2786 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2787 VK_SHARING_MODE_EXCLUSIVE,
2790 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
2793 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
2795 if (ret != VK_SUCCESS) {
2803 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
2805 if (ret != VK_SUCCESS) {
2812 f->queue_family[
i] = p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED : p->img_qfs[0];
2813 f->layout[
i] = create_info.initialLayout;
2815 f->sem_value[
i] = 0;
2831 VkExternalMemoryHandleTypeFlags *comp_handle_types,
2832 VkExternalMemoryHandleTypeFlags *iexp,
2833 VkExternalMemoryHandleTypeFlagBits
exp)
2841 const VkImageDrmFormatModifierListCreateInfoEXT *drm_mod_info =
2843 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
2844 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && drm_mod_info;
2847 VkExternalImageFormatProperties eprops = {
2848 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
2850 VkImageFormatProperties2 props = {
2851 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
2854 VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
2855 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
2857 .pQueueFamilyIndices = p->img_qfs,
2858 .queueFamilyIndexCount = p->nb_img_qfs,
2859 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2860 VK_SHARING_MODE_EXCLUSIVE,
2862 VkPhysicalDeviceExternalImageFormatInfo enext = {
2863 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
2865 .pNext = has_mods ? &phy_dev_mod_info :
NULL,
2867 VkPhysicalDeviceImageFormatInfo2 pinfo = {
2868 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
2869 .pNext = !
exp ?
NULL : &enext,
2870 .format = hwctx->
format[0],
2871 .type = VK_IMAGE_TYPE_2D,
2873 .usage = hwctx->
usage,
2874 .flags = (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && has_mods) ?
2878 nb_mods = has_mods ? drm_mod_info->drmFormatModifierCount : 1;
2879 for (
int i = 0;
i < nb_mods;
i++) {
2881 phy_dev_mod_info.drmFormatModifier = drm_mod_info->pDrmFormatModifiers[
i];
2883 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
2887 av_log(hwfc,
AV_LOG_VERBOSE,
"GetPhysicalDeviceImageFormatProperties2: mod[%d]=0x%llx -> %s\n",
2888 i, (
unsigned long long)phy_dev_mod_info.drmFormatModifier,
2889 ret == VK_SUCCESS ?
"OK" :
"FAIL");
2890 if (ret == VK_SUCCESS) {
2892 *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes;
2893 if (
exp == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) {
2896 VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT);
2904 VkExternalMemoryHandleTypeFlags *comp_handle_types,
2905 VkExternalMemoryHandleTypeFlags *export_types)
2910 *comp_handle_types = 0x0;
2911 *export_types = 0x0;
2915 try_export_flags(hwfc, comp_handle_types, export_types, IsWindows8OrGreater()
2916 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
2917 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
2920 (hwctx->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
2922 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
2925 hwctx->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
2927 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
2939 VkExternalMemoryHandleTypeFlags e;
2942 VkExternalMemoryImageCreateInfo eiinfo = {
2943 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
2950 eminfo[
i].sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
2952 eminfo[
i].handleTypes = e;
2959 av_log(hwfc,
AV_LOG_ERROR,
"vulkan_pool_alloc failed: create_frame failed: %d\n", err);
2967 if ( (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2968 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR))
2970 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)
2972 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR)
2974 else if (hwctx->
usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)
3041 if (p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
3044 "NVIDIA drivers mishandle multi-plane images\n");
3048 const VkImageDrmFormatModifierListCreateInfoEXT *mod_list =
3050 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
3051 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
3052 mod_list && mod_list->drmFormatModifierCount;
3053 int nb_mods = has_mods ? mod_list->drmFormatModifierCount : 1;
3056 if (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && !has_mods)
3059 VkPhysicalDeviceImageDrmFormatModifierInfoEXT mod_info = {
3060 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
3061 .pQueueFamilyIndices = p->img_qfs,
3062 .queueFamilyIndexCount = p->nb_img_qfs,
3063 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3064 VK_SHARING_MODE_EXCLUSIVE,
3066 VkPhysicalDeviceImageFormatInfo2 pinfo = {
3067 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3068 .type = VK_IMAGE_TYPE_2D,
3070 .usage = hwctx->
usage,
3077 VkVideoProfileListInfoKHR profile_list;
3078 const VkVideoProfileListInfoKHR *pl =
3080 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
3083 profile_list.pNext =
NULL;
3087 VkImageFormatListCreateInfo format_list;
3088 const VkImageFormatListCreateInfo *fl =
3090 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO);
3093 format_list.pNext =
NULL;
3100 hwctx->
format[
i] != VK_FORMAT_UNDEFINED;
i++) {
3101 pinfo.format = hwctx->
format[
i];
3105 for (
int j = 0; j < nb_mods; j++) {
3106 VkHostImageCopyDevicePerformanceQueryEXT perf = {
3107 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY_EXT,
3109 VkImageFormatProperties2 props = {
3110 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
3115 mod_info.drmFormatModifier = mod_list->pDrmFormatModifiers[j];
3117 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
3119 if (ret != VK_SUCCESS) {
3121 "format %i is not supported: %s\n",
3126 if (!perf.optimalDeviceAccess) {
3128 "format %i has no optimal device access (identical "
3129 "memory layout: %i)\n",
3130 pinfo.format, perf.identicalMemoryLayout);
3136 if (!p->vkctx.host_image_props.identicalMemoryTypeRequirements) {
3138 VkExternalMemoryHandleTypeFlags e;
3139 VkExternalMemoryImageCreateInfo eiinfo = {
3140 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
3144 VkImageCreateInfo create_info = {
3145 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3146 .pNext = eiinfo.handleTypes ? &eiinfo : hwctx->
create_pnext,
3147 .imageType = VK_IMAGE_TYPE_2D,
3148 .format = hwctx->
format[0],
3154 .usage = hwctx->
usage,
3155 .samples = VK_SAMPLE_COUNT_1_BIT,
3156 .pQueueFamilyIndices = p->img_qfs,
3157 .queueFamilyIndexCount = p->nb_img_qfs,
3158 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3159 VK_SHARING_MODE_EXCLUSIVE,
3161 VkDeviceImageMemoryRequirements req_info = {
3162 .sType = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS,
3163 .pCreateInfo = &create_info,
3164 .planeAspect = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT ?
3165 VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT : 0,
3167 VkMemoryRequirements2 req = {
3168 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3171 vk->GetDeviceImageMemoryRequirements(dev_hwctx->
act_dev, &req_info, &req);
3173 VkMemoryPropertyFlags req_flags = hwctx->
tiling == VK_IMAGE_TILING_LINEAR ?
3174 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
3175 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
3177 if (!(req.memoryRequirements.memoryTypeBits & (1U <<
index)))
3179 if ((p->mprops.memoryTypes[
index].propertyFlags & req_flags) == req_flags)
3182 if (
index == p->mprops.memoryTypeCount) {
3184 "no compatible memory type\n");
3200 VkImageUsageFlags supported_usage;
3203 int disable_multiplane = p->disable_multiplane ||
3205 int is_lone_dpb = ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR) ||
3206 ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
3207 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)));
3214 if (p->use_linear_images &&
3215 (hwctx->
tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
3216 hwctx->
tiling = VK_IMAGE_TILING_LINEAR;
3226 if (hwctx->
format[0] != VK_FORMAT_UNDEFINED) {
3231 "for the current sw_format %s!\n",
3243 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
3252 NULL, &supported_usage,
3255 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
3264 int drm_mod_with_video = (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
3266 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR));
3268 if (!is_lone_dpb && !drm_mod_with_video) {
3270 hwctx->
usage |= supported_usage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT |
3271 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3272 VK_IMAGE_USAGE_STORAGE_BIT |
3273 VK_IMAGE_USAGE_SAMPLED_BIT);
3281 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR))
3282 hwctx->
usage |= supported_usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
3285 if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
3288 hwctx->
usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
3294 int sampleable = hwctx->
usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
3295 VK_IMAGE_USAGE_STORAGE_BIT);
3296 hwctx->
img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
3298 hwctx->
img_flags |= VK_IMAGE_CREATE_ALIAS_BIT;
3300 hwctx->
img_flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
3309 if ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
3312 const VkVideoProfileListInfoKHR *pl;
3315 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
3318 for (
i = 0;
i < pl->profileCount;
i++) {
3320 if (pl->pProfiles[
i].videoCodecOperation & 0xFFFF0000)
3323 if (
i == pl->profileCount)
3324 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
3329 if ((hwctx->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT) &&
3331 hwctx->
usage &= ~VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
3362 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
3363 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
3365 err = vk->GetImageDrmFormatModifierPropertiesEXT(dev_hwctx->
act_dev,
f->img[0],
3367 if (err != VK_SUCCESS) {
3373 VkDrmFormatModifierPropertiesListEXT modp;
3374 VkFormatProperties2 fmtp;
3375 VkDrmFormatModifierPropertiesEXT *mod_props =
NULL;
3377 modp = (VkDrmFormatModifierPropertiesListEXT) {
3378 .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
3380 fmtp = (VkFormatProperties2) {
3381 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
3386 vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->
phys_dev, fmt->
fallback[
i], &fmtp);
3388 modp.pDrmFormatModifierProperties =
3389 av_calloc(modp.drmFormatModifierCount,
sizeof(*modp.pDrmFormatModifierProperties));
3390 if (!modp.pDrmFormatModifierProperties) {
3394 vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->
phys_dev, fmt->
fallback[
i], &fmtp);
3396 for (uint32_t j = 0; j < modp.drmFormatModifierCount; ++j) {
3397 VkDrmFormatModifierPropertiesEXT *m = &modp.pDrmFormatModifierProperties[j];
3398 if (m->drmFormatModifier == drm_mod.drmFormatModifier) {
3404 if (mod_props ==
NULL) {
3405 av_log(hwfc,
AV_LOG_ERROR,
"No DRM format modifier properties found for modifier 0x%016"PRIx64
"\n",
3406 drm_mod.drmFormatModifier);
3407 av_free(modp.pDrmFormatModifierProperties);
3413 av_free(modp.pDrmFormatModifierProperties);
3477static const struct {
3478 uint32_t drm_fourcc;
3480} vulkan_drm_format_map[] = {
3481 { DRM_FORMAT_R8, VK_FORMAT_R8_UNORM },
3482 { DRM_FORMAT_R16, VK_FORMAT_R16_UNORM },
3483 { DRM_FORMAT_GR88, VK_FORMAT_R8G8_UNORM },
3484 { DRM_FORMAT_RG88, VK_FORMAT_R8G8_UNORM },
3485 { DRM_FORMAT_GR1616, VK_FORMAT_R16G16_UNORM },
3486 { DRM_FORMAT_RG1616, VK_FORMAT_R16G16_UNORM },
3487 { DRM_FORMAT_ARGB8888, VK_FORMAT_B8G8R8A8_UNORM },
3488 { DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM },
3489 { DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM },
3490 { DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM },
3491 { DRM_FORMAT_ARGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
3492 { DRM_FORMAT_ABGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
3493 { DRM_FORMAT_XRGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
3494 { DRM_FORMAT_XBGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
3497#ifdef DRM_FORMAT_XYUV8888
3498 { DRM_FORMAT_XYUV8888, VK_FORMAT_R8G8B8A8_UNORM },
3499 { DRM_FORMAT_XVYU2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 } ,
3500 { DRM_FORMAT_XVYU12_16161616, VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 } ,
3501 { DRM_FORMAT_XVYU16161616, VK_FORMAT_R16G16B16A16_UNORM } ,
3505static inline VkFormat drm_to_vulkan_fmt(uint32_t drm_fourcc)
3508 if (vulkan_drm_format_map[
i].drm_fourcc == drm_fourcc)
3509 return vulkan_drm_format_map[
i].vk_format;
3510 return VK_FORMAT_UNDEFINED;
3519 int bind_counts = 0;
3528 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3529 if (drm_to_vulkan_fmt(
desc->layers[
i].format) == VK_FORMAT_UNDEFINED) {
3531 desc->layers[
i].format);
3542 f->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
3544 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3548 VkSemaphoreTypeCreateInfo sem_type_info = {
3549 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3550 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
3553 VkSemaphoreCreateInfo sem_spawn = {
3554 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3555 .pNext = &sem_type_info,
3560 VkImageDrmFormatModifierExplicitCreateInfoEXT ext_img_mod_spec = {
3561 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
3562 .drmFormatModifier =
desc->objects[0].format_modifier,
3563 .drmFormatModifierPlaneCount =
planes,
3564 .pPlaneLayouts = (
const VkSubresourceLayout *)&ext_img_layouts,
3566 VkExternalMemoryImageCreateInfo ext_img_spec = {
3567 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
3568 .pNext = &ext_img_mod_spec,
3569 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3571 VkImageCreateInfo create_info = {
3572 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3573 .pNext = &ext_img_spec,
3574 .imageType = VK_IMAGE_TYPE_2D,
3575 .format = drm_to_vulkan_fmt(
desc->layers[
i].format),
3580 .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
3581 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
3583 .samples = VK_SAMPLE_COUNT_1_BIT,
3584 .pQueueFamilyIndices =
p->img_qfs,
3585 .queueFamilyIndexCount =
p->nb_img_qfs,
3586 .sharingMode =
p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3587 VK_SHARING_MODE_EXCLUSIVE,
3598 if (sw_vkfmts && sw_vkfmts[
i] != VK_FORMAT_UNDEFINED)
3599 create_info.format = sw_vkfmts[
i];
3603 VkExternalImageFormatProperties ext_props = {
3604 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
3606 VkImageFormatProperties2 props_ret = {
3607 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
3608 .pNext = &ext_props,
3610 VkPhysicalDeviceImageDrmFormatModifierInfoEXT props_drm_mod = {
3611 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
3612 .drmFormatModifier = ext_img_mod_spec.drmFormatModifier,
3613 .pQueueFamilyIndices = create_info.pQueueFamilyIndices,
3614 .queueFamilyIndexCount = create_info.queueFamilyIndexCount,
3615 .sharingMode = create_info.sharingMode,
3617 VkPhysicalDeviceExternalImageFormatInfo props_ext = {
3618 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
3619 .pNext = &props_drm_mod,
3620 .handleType = ext_img_spec.handleTypes,
3622 VkPhysicalDeviceImageFormatInfo2 fmt_props;
3625 create_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT |
3626 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3628 create_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT |
3629 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3631 fmt_props = (VkPhysicalDeviceImageFormatInfo2) {
3632 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3633 .pNext = &props_ext,
3634 .format = create_info.format,
3635 .type = create_info.imageType,
3636 .tiling = create_info.tiling,
3637 .usage = create_info.usage,
3638 .flags = create_info.flags,
3642 ret = vk->GetPhysicalDeviceImageFormatProperties2(hwctx->phys_dev,
3643 &fmt_props, &props_ret);
3644 if (ret != VK_SUCCESS) {
3652 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
3653 hwfc->sw_format,
src->width,
src->height,
i);
3656 for (
int j = 0; j <
planes; j++) {
3657 ext_img_layouts[j].offset =
desc->layers[
i].planes[j].offset;
3658 ext_img_layouts[j].rowPitch =
desc->layers[
i].planes[j].pitch;
3659 ext_img_layouts[j].size = 0;
3660 ext_img_layouts[j].arrayPitch = 0;
3661 ext_img_layouts[j].depthPitch = 0;
3665 ret = vk->CreateImage(hwctx->act_dev, &create_info,
3666 hwctx->alloc, &
f->img[
i]);
3667 if (ret != VK_SUCCESS) {
3674 ret = vk->CreateSemaphore(hwctx->act_dev, &sem_spawn,
3675 hwctx->alloc, &
f->sem[
i]);
3676 if (ret != VK_SUCCESS) {
3683 f->queue_family[
i] = VK_QUEUE_FAMILY_EXTERNAL;
3684 f->layout[
i] = create_info.initialLayout;
3686 f->sem_value[
i] = 0;
3689 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3691 VkImageMemoryRequirementsInfo2 req_desc = {
3692 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
3695 VkMemoryDedicatedRequirements ded_req = {
3696 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
3698 VkMemoryRequirements2 req2 = {
3699 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3704 VkMemoryFdPropertiesKHR fdmp = {
3705 .sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR,
3711 VkImportMemoryFdInfoKHR idesc = {
3712 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
3713 .fd = dup(
desc->objects[
desc->layers[
i].planes[0].object_index].fd),
3714 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3716 VkMemoryDedicatedAllocateInfo ded_alloc = {
3717 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
3719 .image = req_desc.image,
3723 ret = vk->GetMemoryFdPropertiesKHR(hwctx->act_dev,
3724 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3726 if (ret != VK_SUCCESS) {
3734 vk->GetImageMemoryRequirements2(hwctx->act_dev, &req_desc, &req2);
3737 req2.memoryRequirements.memoryTypeBits = fdmp.memoryTypeBits;
3740 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
3741 (ded_req.prefersDedicatedAllocation ||
3742 ded_req.requiresDedicatedAllocation) ?
3743 &ded_alloc : ded_alloc.pNext,
3744 &
f->flags, &
f->mem[
i]);
3750 f->size[
i] = req2.memoryRequirements.size;
3753 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3755 for (
int j = 0; j <
planes; j++) {
3756 VkImageAspectFlagBits aspect = j == 0 ? VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT :
3757 j == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3758 VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
3760 plane_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO;
3762 plane_info[bind_counts].planeAspect = aspect;
3764 bind_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
3766 bind_info[bind_counts].image =
f->img[
i];
3767 bind_info[bind_counts].memory =
f->mem[
i];
3770 bind_info[bind_counts].memoryOffset = 0;
3777 ret = vk->BindImageMemory2(hwctx->act_dev, bind_counts, bind_info);
3778 if (ret != VK_SUCCESS) {
3806#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
3808 VkCommandBuffer cmd_buf;
3814 for (
int i = 0;
i <
desc->nb_objects;
i++) {
3815 VkSemaphoreTypeCreateInfo sem_type_info = {
3816 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3817 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
3819 VkSemaphoreCreateInfo sem_spawn = {
3820 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3821 .pNext = &sem_type_info,
3823 VkImportSemaphoreFdInfoKHR import_info;
3824 struct dma_buf_export_sync_file implicit_fd_info = {
3825 .flags = DMA_BUF_SYNC_READ,
3829 if (ioctl(
desc->objects[
i].fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE,
3830 &implicit_fd_info)) {
3835 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3839 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3840 hwctx->
alloc, &drm_sync_sem[
i]);
3841 if (ret != VK_SUCCESS) {
3846 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3850 import_info = (VkImportSemaphoreFdInfoKHR) {
3851 .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
3852 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
3853 .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
3854 .semaphore = drm_sync_sem[
i],
3855 .fd = implicit_fd_info.fd,
3858 ret = vk->ImportSemaphoreFdKHR(hwctx->
act_dev, &import_info);
3859 if (ret != VK_SUCCESS) {
3864 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3870 cmd_buf = exec->
buf;
3874 for (
int i = 0;
i <
desc->nb_objects;
i++)
3875 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3881 drm_sync_sem,
desc->nb_objects,
3882 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 1);
3885 VK_PIPELINE_STAGE_2_NONE,
3886 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
3893 VK_PIPELINE_STAGE_2_NONE,
3894 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
3896 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT : 0x0) |
3898 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT : 0x0),
3899 VK_IMAGE_LAYOUT_GENERAL,
3900 p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED :
p->img_qfs[0]);
3902 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
3903 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
3904 .pImageMemoryBarriers = img_bar,
3905 .imageMemoryBarrierCount = nb_img_bar,
3916 "image may be corrupted.\n");
3932 if ((err = vulkan_map_from_drm_frame_desc(hwfc, &
f,
src,
flags)))
3936 dst->data[0] = (uint8_t *)
f;
3938 dst->height =
src->height;
3941 &vulkan_unmap_from_drm,
f);
3945 err = vulkan_map_from_drm_frame_sync(hwfc,
dst,
desc,
flags);
3968 VASurfaceID surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
3974 vaSyncSurface(vaapi_ctx->
display, surface_id);
3982 err = vulkan_map_from_drm(dst_fc,
dst,
tmp,
flags);
3999 VkDeviceMemory mem,
size_t size)
4007 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
4008 .type = IsWindows8OrGreater()
4009 ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
4010 : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT,
4013 VkMemoryGetWin32HandleInfoKHR export_info = {
4014 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
4016 .handleType = IsWindows8OrGreater()
4017 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
4018 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
4021 ret = vk->GetMemoryWin32HandleKHR(hwctx->
act_dev, &export_info,
4022 &ext_desc.handle.win32.handle);
4023 if (ret != VK_SUCCESS) {
4028 dst_int->ext_mem_handle[idx] = ext_desc.handle.win32.handle;
4030 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
4031 .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
4034 VkMemoryGetFdInfoKHR export_info = {
4035 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
4037 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
4040 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
4041 &ext_desc.handle.fd);
4042 if (ret != VK_SUCCESS) {
4049 ret =
CHECK_CU(cu->cuImportExternalMemory(&dst_int->ext_mem[idx], &ext_desc));
4052 close(ext_desc.handle.fd);
4071 VkSemaphoreGetWin32HandleInfoKHR sem_export = {
4072 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
4074 .handleType = IsWindows8OrGreater()
4075 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
4076 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
4078 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
4082 VkSemaphoreGetFdInfoKHR sem_export = {
4083 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
4085 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
4087 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
4093 ret = vk->GetSemaphoreWin32HandleKHR(hwctx->
act_dev, &sem_export,
4094 &ext_sem_desc.handle.win32.handle);
4096 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &sem_export,
4097 &ext_sem_desc.handle.fd);
4099 if (ret != VK_SUCCESS) {
4105 dst_int->ext_sem_handle[idx] = ext_sem_desc.handle.win32.handle;
4108 ret =
CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[idx],
4112 close(ext_sem_desc.handle.fd);
4140 CudaFunctions *cu = cu_internal->
cuda_dl;
4141 CUarray_format cufmt =
desc->comp[0].depth > 8 ? CU_AD_FORMAT_UNSIGNED_INT16 :
4142 CU_AD_FORMAT_UNSIGNED_INT8;
4143 const int elem_size = 1 + (
desc->comp[0].depth > 8);
4146 dst_int = dst_f->internal;
4148 if (!dst_int->cuda_fc_ref) {
4152 if (!dst_int->cuda_fc_ref)
4156 for (
int i = 0;
i < nb_images;
i++) {
4157 err = export_mem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
4158 dst_f->mem[
i], dst_f->size[
i]);
4162 err = export_sem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
4168 if (nb_images !=
planes) {
4172 if (
desc->comp[
i].step / elem_size > 1) {
4174 "Cannot map a multiplane Vulkan image (%d image(s) "
4175 "for %d plane(s)) to CUDA; create the Vulkan device "
4176 "with the disable_multiplane=1 option (one image per "
4177 "plane) for CUDA interop.\n", nb_images,
planes);
4182 VkImageSubresource subres = {
4183 .aspectMask =
i == 2 ? VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT :
4184 i == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
4185 VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT
4187 VkSubresourceLayout
layout = { 0 };
4188 vk->GetImageSubresourceLayout(hwctx->
act_dev, dst_f->img[
FFMIN(
i, nb_images - 1)],
4195 CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = {
4200 .NumChannels =
desc->comp[
i].step / elem_size,
4208 tex_desc.arrayDesc.Width = p_w;
4209 tex_desc.arrayDesc.Height = p_h;
4211 ret =
CHECK_CU(cu->cuExternalMemoryGetMappedMipmappedArray(&dst_int->cu_mma[
i],
4212 dst_int->ext_mem[
FFMIN(
i, nb_images - 1)],
4219 ret =
CHECK_CU(cu->cuMipmappedArrayGetLevel(&dst_int->cu_array[
i],
4220 dst_int->cu_mma[
i], 0));
4253 CudaFunctions *cu = cu_internal->
cuda_dl;
4264 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
4268 err = vulkan_export_to_cuda(hwfc,
src->hw_frames_ctx,
dst);
4274 dst_int = dst_f->internal;
4276 for (
int i = 0;
i < nb_images;
i++) {
4277 s_w_par[
i].params.fence.value = dst_f->sem_value[
i] + 0;
4278 s_s_par[
i].params.fence.value = dst_f->sem_value[
i] + 1;
4281 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
4282 nb_images, cuda_dev->stream));
4287 CUDA_MEMCPY2D cpy = {
4288 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
4289 .srcDevice = (CUdeviceptr)
src->data[
i],
4290 .srcPitch =
src->linesize[
i],
4293 .dstMemoryType = CU_MEMORYTYPE_ARRAY,
4294 .dstArray = dst_int->cu_array[
i],
4300 cpy.WidthInBytes = p_w *
desc->comp[
i].step;
4303 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
4308 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
4309 nb_images, cuda_dev->stream));
4313 for (
int i = 0;
i < nb_images;
i++)
4314 dst_f->sem_value[
i]++;
4335 switch (
src->format) {
4340 return vulkan_map_from_vaapi(hwfc,
dst,
src,
flags);
4346 return vulkan_map_from_drm(hwfc,
dst,
src,
flags);
4356typedef struct VulkanDRMMapping {
4357 AVDRMFrameDescriptor drm_desc;
4375static inline uint32_t vulkan_fmt_to_drm(
VkFormat vkfmt)
4378 if (vulkan_drm_format_map[
i].vk_format == vkfmt)
4379 return vulkan_drm_format_map[
i].drm_fourcc;
4380 return DRM_FORMAT_INVALID;
4383#define MAX_MEMORY_PLANES 4
4384static VkImageAspectFlags plane_index_to_aspect(
int plane) {
4385 if (plane == 0)
return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
4386 if (plane == 1)
return VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT;
4387 if (plane == 2)
return VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
4388 if (plane == 3)
return VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT;
4391 return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
4394#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
4404 if (
f->internal->drm_sync_sem == VK_NULL_HANDLE) {
4405 VkExportSemaphoreCreateInfo exp_info = {
4406 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
4407 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
4409 VkSemaphoreTypeCreateInfo type_info = {
4410 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
4412 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
4414 VkSemaphoreCreateInfo sem_create = {
4415 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
4416 .pNext = &type_info,
4418 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_create, hwctx->
alloc,
4419 &
f->internal->drm_sync_sem);
4420 if (ret != VK_SUCCESS) {
4432 for (
int i = 0;
i < nb_sems;
i++)
4435 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
4437 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 0);
4439 VkSemaphoreGetFdInfoKHR get_fd_info = {
4440 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
4441 .semaphore =
f->internal->drm_sync_sem,
4442 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
4444 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &get_fd_info, &sync_fd);
4445 if (ret != VK_SUCCESS) {
4447 "Failed to get sync fd from DRM map export semaphore: %s\n",
4470 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
4471 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
4473 const int nb_sems = nb_images;
4474 int free_drm_desc_on_err = 1;
4485#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
4487 f->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
4488 vk->GetSemaphoreFdKHR && vk->CreateSemaphore) {
4489 err = vulkan_drm_export_sync_fd(hwfc,
f, fp, nb_sems);
4498 VkSemaphoreWaitInfo wait_info = {
4499 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
4501 .semaphoreCount = nb_sems,
4502 .pSemaphores =
f->sem,
4503 .pValues =
f->sem_value,
4505 vk->WaitSemaphores(hwctx->
act_dev, &wait_info, UINT64_MAX);
4513 free_drm_desc_on_err = 0;
4515 ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->
act_dev,
f->img[0],
4517 if (ret != VK_SUCCESS) {
4523 for (
int i = 0; (
i <
planes) && (
f->mem[
i]);
i++) {
4524 VkMemoryGetFdInfoKHR export_info = {
4525 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
4526 .memory =
f->mem[
i],
4527 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
4530 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
4532 if (ret != VK_SUCCESS) {
4538#if HAVE_LINUX_DMA_BUF_H && defined(DMA_BUF_IOCTL_IMPORT_SYNC_FILE)
4540 int dup_fd = dup(sync_fd);
4542 struct dma_buf_import_sync_file import_info = {
4543 .flags = DMA_BUF_SYNC_WRITE,
4546 if (ioctl(drm_desc->
objects[
i].
fd, DMA_BUF_IOCTL_IMPORT_SYNC_FILE, &import_info) < 0)
4565 drm_desc->
layers[
i].
format = vulkan_fmt_to_drm(plane_vkfmt);
4575 VkSubresourceLayout
layout;
4576 int aspect_plane = (nb_images == 1) ?
i : j;
4577 VkImageSubresource sub = {
4578 .aspectMask = plane_index_to_aspect(aspect_plane),
4595 if (
f->tiling == VK_IMAGE_TILING_OPTIMAL)
4601 dst->height =
src->height;
4602 dst->data[0] = (uint8_t *)drm_desc;
4615 if (free_drm_desc_on_err)
4655 switch (
dst->format) {
4665 return vulkan_map_to_vaapi(hwfc,
dst,
src,
flags);
4677 AVFrame *swf, VkBufferImageCopy *region,
4686 region[
i].bufferRowLength,
4690 region[
i].imageExtent.height);
4693 if (err != VK_SUCCESS) {
4700 if (err != VK_SUCCESS) {
4710 region[
i].bufferRowLength,
4712 region[
i].imageExtent.height);
4719 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4726 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4727 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4729 size_t buf_offset = 0;
4733 region[
i] = (VkBufferImageCopy) {
4734 .bufferOffset = buf_offset,
4736 p->props.properties.limits.optimalBufferCopyRowPitchAlignment),
4737 .bufferImageHeight = p_h,
4738 .imageSubresource.layerCount = 1,
4739 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4743 buf_offset +=
FFALIGN(p_h*region[
i].bufferRowLength,
4744 p->props.properties.limits.optimalBufferCopyOffsetAlignment);
4749 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
4750 p->vkctx.host_cached_flag);
4758 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4765 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4766 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4775 while (swf->
buf[nb_src_bufs])
4779 if (nb_src_bufs == 1) {
4781 swf->
data[0], VK_WHOLE_SIZE, swf->
buf[0],
4788 region[
i].bufferOffset =
dst[0]->virtual_offset +
4790 }
else if (nb_src_bufs ==
planes) {
4793 swf->
data[
i], VK_WHOLE_SIZE,
4794 swf->
buf[
i], buf_usage);
4799 region[
i].bufferOffset =
dst[
i]->virtual_offset;
4809 for (
int i = 0;
i < (*nb_bufs);
i++)
4830 int nb_layout_ch = 0;
4834 for (
int i = 0;
i < nb_images;
i++) {
4836 for (
int j = 0; j < p->vkctx.host_image_props.copySrcLayoutCount; j++) {
4837 if (hwf_vk->
layout[
i] == p->vkctx.host_image_props.pCopySrcLayouts[j]) {
4847 layout_ch_info[nb_layout_ch] = (VkHostImageLayoutTransitionInfoEXT) {
4848 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT,
4849 .image = hwf_vk->
img[
i],
4850 .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
4851 .newLayout = VK_IMAGE_LAYOUT_GENERAL,
4852 .subresourceRange = {
4853 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4859 hwf_vk->
layout[
i] = layout_ch_info[nb_layout_ch].newLayout;
4864 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
4865 .pSemaphores = hwf_vk->
sem,
4867 .semaphoreCount = nb_images,
4873 vk->TransitionImageLayoutEXT(hwctx->
act_dev,
4874 nb_layout_ch, layout_ch_info);
4877 VkMemoryToImageCopyEXT region_info = {
4878 .sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT,
4879 .imageSubresource = {
4883 VkCopyMemoryToImageInfoEXT copy_info = {
4884 .sType = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT,
4886 .pRegions = ®ion_info,
4889 int img_idx =
FFMIN(
i, (nb_images - 1));
4893 region_info.pHostPointer = swf->
data[
i];
4894 region_info.memoryRowLength = swf->
linesize[
i] /
desc->comp[
i].step;
4896 region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 };
4897 copy_info.dstImage = hwf_vk->
img[img_idx];
4898 copy_info.dstImageLayout = hwf_vk->
layout[img_idx];
4900 vk->CopyMemoryToImageEXT(hwctx->
act_dev, ©_info);
4903 VkImageToMemoryCopyEXT region_info = {
4904 .sType = VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT,
4905 .imageSubresource = {
4909 VkCopyImageToMemoryInfoEXT copy_info = {
4910 .sType = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT,
4912 .pRegions = ®ion_info,
4915 int img_idx =
FFMIN(
i, (nb_images - 1));
4919 region_info.pHostPointer = swf->
data[
i];
4920 region_info.memoryRowLength = swf->
linesize[
i] /
desc->comp[
i].step;
4922 region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 };
4923 copy_info.srcImage = hwf_vk->
img[img_idx];
4924 copy_info.srcImageLayout = hwf_vk->
layout[img_idx];
4926 vk->CopyImageToMemoryEXT(hwctx->
act_dev, ©_info);
4945 int host_mapped = 0;
4960 VkCommandBuffer cmd_buf;
4972 int host_copy = hwctx->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
4975 if (!upload && host_copy) {
4976 for (
int i = 0;
i < nb_images;
i++) {
4978 for (
int j = 0; j < p->vkctx.host_image_props.copySrcLayoutCount; j++) {
4979 if (hwf_vk->
layout[
i] == p->vkctx.host_image_props.pCopySrcLayouts[j]) {
4999 region[
i] = (VkBufferImageCopy) {
5002 .bufferImageHeight = p_h,
5003 .imageSubresource.layerCount = 1,
5004 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
5030 cmd_buf = exec->
buf;
5038 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
5039 VK_PIPELINE_STAGE_2_TRANSFER_BIT);
5057 for (
int i = 0;
i < nb_bufs;
i++)
5062 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
5063 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,
5064 upload ? VK_ACCESS_TRANSFER_WRITE_BIT :
5065 VK_ACCESS_TRANSFER_READ_BIT,
5066 upload ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL :
5067 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5068 p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED : p->img_qfs[0]);
5070 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
5071 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
5072 .pImageMemoryBarriers = img_bar,
5073 .imageMemoryBarrierCount = nb_img_bar,
5077 int buf_idx =
FFMIN(
i, (nb_bufs - 1));
5078 int img_idx =
FFMIN(
i, (nb_images - 1));
5081 uint32_t orig_stride = region[
i].bufferRowLength;
5082 region[
i].bufferRowLength /=
desc->comp[
i].step;
5086 vk->CmdCopyBufferToImage(cmd_buf, vkbuf->
buf,
5087 hwf_vk->
img[img_idx],
5088 img_bar[img_idx].newLayout,
5091 vk->CmdCopyImageToBuffer(cmd_buf, hwf_vk->
img[img_idx],
5092 img_bar[img_idx].newLayout,
5096 region[
i].bufferRowLength = orig_stride;
5100 if (err >= 0 && !upload) {
5107 for (
int i = 0;
i < nb_bufs;
i++)
5118 switch (
src->format) {
5128 return vulkan_transfer_data_from_cuda(hwfc,
dst,
src);
5132 if (
src->hw_frames_ctx)
5157 CudaFunctions *cu = cu_internal->
cuda_dl;
5168 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
5172 err = vulkan_export_to_cuda(hwfc,
dst->hw_frames_ctx,
src);
5178 dst_int = dst_f->internal;
5180 for (
int i = 0;
i < nb_images;
i++) {
5181 s_w_par[
i].params.fence.value = dst_f->sem_value[
i] + 0;
5182 s_s_par[
i].params.fence.value = dst_f->sem_value[
i] + 1;
5185 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
5186 nb_images, cuda_dev->stream));
5191 CUDA_MEMCPY2D cpy = {
5192 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
5193 .dstDevice = (CUdeviceptr)
dst->data[
i],
5194 .dstPitch =
dst->linesize[
i],
5197 .srcMemoryType = CU_MEMORYTYPE_ARRAY,
5198 .srcArray = dst_int->cu_array[
i],
5204 cpy.WidthInBytes =
w *
desc->comp[
i].step;
5207 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
5212 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
5213 nb_images, cuda_dev->stream));
5217 for (
int i = 0;
i < nb_images;
i++)
5218 dst_f->sem_value[
i]++;
5239 switch (
dst->format) {
5249 return vulkan_transfer_data_to_cuda(hwfc,
dst,
src);
5253 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.
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
#define AV_CEIL_RSHIFT(a, b)
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
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_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.