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)
3036 const VkImageDrmFormatModifierListCreateInfoEXT *mod_list =
3038 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
3039 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
3040 mod_list && mod_list->drmFormatModifierCount;
3041 int nb_mods = has_mods ? mod_list->drmFormatModifierCount : 1;
3044 if (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && !has_mods)
3047 VkPhysicalDeviceImageDrmFormatModifierInfoEXT mod_info = {
3048 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
3049 .pQueueFamilyIndices = p->img_qfs,
3050 .queueFamilyIndexCount = p->nb_img_qfs,
3051 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3052 VK_SHARING_MODE_EXCLUSIVE,
3054 VkPhysicalDeviceImageFormatInfo2 pinfo = {
3055 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3056 .type = VK_IMAGE_TYPE_2D,
3058 .usage = hwctx->
usage,
3065 VkVideoProfileListInfoKHR profile_list;
3066 const VkVideoProfileListInfoKHR *pl =
3068 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
3071 profile_list.pNext =
NULL;
3075 VkImageFormatListCreateInfo format_list;
3076 const VkImageFormatListCreateInfo *fl =
3078 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO);
3081 format_list.pNext =
NULL;
3088 hwctx->
format[
i] != VK_FORMAT_UNDEFINED;
i++) {
3089 pinfo.format = hwctx->
format[
i];
3093 for (
int j = 0; j < nb_mods; j++) {
3094 VkHostImageCopyDevicePerformanceQueryEXT perf = {
3095 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY_EXT,
3097 VkImageFormatProperties2 props = {
3098 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
3103 mod_info.drmFormatModifier = mod_list->pDrmFormatModifiers[j];
3105 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
3107 if (ret != VK_SUCCESS) {
3109 "format %i is not supported: %s\n",
3114 if (!perf.optimalDeviceAccess) {
3116 "format %i has no optimal device access (identical "
3117 "memory layout: %i)\n",
3118 pinfo.format, perf.identicalMemoryLayout);
3124 if (!p->vkctx.host_image_props.identicalMemoryTypeRequirements) {
3126 VkExternalMemoryHandleTypeFlags e;
3127 VkExternalMemoryImageCreateInfo eiinfo = {
3128 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
3132 VkImageCreateInfo create_info = {
3133 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3134 .pNext = eiinfo.handleTypes ? &eiinfo : hwctx->
create_pnext,
3135 .imageType = VK_IMAGE_TYPE_2D,
3136 .format = hwctx->
format[0],
3142 .usage = hwctx->
usage,
3143 .samples = VK_SAMPLE_COUNT_1_BIT,
3144 .pQueueFamilyIndices = p->img_qfs,
3145 .queueFamilyIndexCount = p->nb_img_qfs,
3146 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3147 VK_SHARING_MODE_EXCLUSIVE,
3149 VkDeviceImageMemoryRequirements req_info = {
3150 .sType = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS,
3151 .pCreateInfo = &create_info,
3152 .planeAspect = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT ?
3153 VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT : 0,
3155 VkMemoryRequirements2 req = {
3156 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3159 vk->GetDeviceImageMemoryRequirements(dev_hwctx->
act_dev, &req_info, &req);
3161 VkMemoryPropertyFlags req_flags = hwctx->
tiling == VK_IMAGE_TILING_LINEAR ?
3162 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
3163 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
3165 if (!(req.memoryRequirements.memoryTypeBits & (1U <<
index)))
3167 if ((p->mprops.memoryTypes[
index].propertyFlags & req_flags) == req_flags)
3170 if (
index == p->mprops.memoryTypeCount) {
3172 "no compatible memory type\n");
3188 VkImageUsageFlags supported_usage;
3191 int disable_multiplane = p->disable_multiplane ||
3193 int is_lone_dpb = ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR) ||
3194 ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
3195 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)));
3202 if (p->use_linear_images &&
3203 (hwctx->
tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
3204 hwctx->
tiling = VK_IMAGE_TILING_LINEAR;
3214 if (hwctx->
format[0] != VK_FORMAT_UNDEFINED) {
3219 "for the current sw_format %s!\n",
3231 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
3240 NULL, &supported_usage,
3243 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
3252 int drm_mod_with_video = (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
3254 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR));
3256 if (!is_lone_dpb && !drm_mod_with_video) {
3258 hwctx->
usage |= supported_usage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT |
3259 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3260 VK_IMAGE_USAGE_STORAGE_BIT |
3261 VK_IMAGE_USAGE_SAMPLED_BIT);
3269 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR))
3270 hwctx->
usage |= supported_usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
3273 if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
3276 hwctx->
usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
3282 int sampleable = hwctx->
usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
3283 VK_IMAGE_USAGE_STORAGE_BIT);
3284 hwctx->
img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
3286 hwctx->
img_flags |= VK_IMAGE_CREATE_ALIAS_BIT;
3288 hwctx->
img_flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
3297 if ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
3300 const VkVideoProfileListInfoKHR *pl;
3303 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
3306 for (
i = 0;
i < pl->profileCount;
i++) {
3308 if (pl->pProfiles[
i].videoCodecOperation & 0xFFFF0000)
3311 if (
i == pl->profileCount)
3312 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
3317 if ((hwctx->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT) &&
3319 hwctx->
usage &= ~VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
3350 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
3351 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
3353 err = vk->GetImageDrmFormatModifierPropertiesEXT(dev_hwctx->
act_dev,
f->img[0],
3355 if (err != VK_SUCCESS) {
3361 VkDrmFormatModifierPropertiesListEXT modp;
3362 VkFormatProperties2 fmtp;
3363 VkDrmFormatModifierPropertiesEXT *mod_props =
NULL;
3365 modp = (VkDrmFormatModifierPropertiesListEXT) {
3366 .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
3368 fmtp = (VkFormatProperties2) {
3369 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
3374 vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->
phys_dev, fmt->
fallback[
i], &fmtp);
3376 modp.pDrmFormatModifierProperties =
3377 av_calloc(modp.drmFormatModifierCount,
sizeof(*modp.pDrmFormatModifierProperties));
3378 if (!modp.pDrmFormatModifierProperties) {
3382 vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->
phys_dev, fmt->
fallback[
i], &fmtp);
3384 for (uint32_t j = 0; j < modp.drmFormatModifierCount; ++j) {
3385 VkDrmFormatModifierPropertiesEXT *m = &modp.pDrmFormatModifierProperties[j];
3386 if (m->drmFormatModifier == drm_mod.drmFormatModifier) {
3392 if (mod_props ==
NULL) {
3393 av_log(hwfc,
AV_LOG_ERROR,
"No DRM format modifier properties found for modifier 0x%016"PRIx64
"\n",
3394 drm_mod.drmFormatModifier);
3395 av_free(modp.pDrmFormatModifierProperties);
3401 av_free(modp.pDrmFormatModifierProperties);
3465static const struct {
3466 uint32_t drm_fourcc;
3468} vulkan_drm_format_map[] = {
3469 { DRM_FORMAT_R8, VK_FORMAT_R8_UNORM },
3470 { DRM_FORMAT_R16, VK_FORMAT_R16_UNORM },
3471 { DRM_FORMAT_GR88, VK_FORMAT_R8G8_UNORM },
3472 { DRM_FORMAT_RG88, VK_FORMAT_R8G8_UNORM },
3473 { DRM_FORMAT_GR1616, VK_FORMAT_R16G16_UNORM },
3474 { DRM_FORMAT_RG1616, VK_FORMAT_R16G16_UNORM },
3475 { DRM_FORMAT_ARGB8888, VK_FORMAT_B8G8R8A8_UNORM },
3476 { DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM },
3477 { DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM },
3478 { DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM },
3479 { DRM_FORMAT_ARGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
3480 { DRM_FORMAT_ABGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
3481 { DRM_FORMAT_XRGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
3482 { DRM_FORMAT_XBGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
3485#ifdef DRM_FORMAT_XYUV8888
3486 { DRM_FORMAT_XYUV8888, VK_FORMAT_R8G8B8A8_UNORM },
3487 { DRM_FORMAT_XVYU2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 } ,
3488 { DRM_FORMAT_XVYU12_16161616, VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 } ,
3489 { DRM_FORMAT_XVYU16161616, VK_FORMAT_R16G16B16A16_UNORM } ,
3493static inline VkFormat drm_to_vulkan_fmt(uint32_t drm_fourcc)
3496 if (vulkan_drm_format_map[
i].drm_fourcc == drm_fourcc)
3497 return vulkan_drm_format_map[
i].vk_format;
3498 return VK_FORMAT_UNDEFINED;
3507 int bind_counts = 0;
3516 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3517 if (drm_to_vulkan_fmt(
desc->layers[
i].format) == VK_FORMAT_UNDEFINED) {
3519 desc->layers[
i].format);
3530 f->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
3532 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3536 VkSemaphoreTypeCreateInfo sem_type_info = {
3537 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3538 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
3541 VkSemaphoreCreateInfo sem_spawn = {
3542 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3543 .pNext = &sem_type_info,
3548 VkImageDrmFormatModifierExplicitCreateInfoEXT ext_img_mod_spec = {
3549 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
3550 .drmFormatModifier =
desc->objects[0].format_modifier,
3551 .drmFormatModifierPlaneCount =
planes,
3552 .pPlaneLayouts = (
const VkSubresourceLayout *)&ext_img_layouts,
3554 VkExternalMemoryImageCreateInfo ext_img_spec = {
3555 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
3556 .pNext = &ext_img_mod_spec,
3557 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3559 VkImageCreateInfo create_info = {
3560 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3561 .pNext = &ext_img_spec,
3562 .imageType = VK_IMAGE_TYPE_2D,
3563 .format = drm_to_vulkan_fmt(
desc->layers[
i].format),
3568 .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
3569 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
3571 .samples = VK_SAMPLE_COUNT_1_BIT,
3572 .pQueueFamilyIndices =
p->img_qfs,
3573 .queueFamilyIndexCount =
p->nb_img_qfs,
3574 .sharingMode =
p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3575 VK_SHARING_MODE_EXCLUSIVE,
3586 if (sw_vkfmts && sw_vkfmts[
i] != VK_FORMAT_UNDEFINED)
3587 create_info.format = sw_vkfmts[
i];
3591 VkExternalImageFormatProperties ext_props = {
3592 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
3594 VkImageFormatProperties2 props_ret = {
3595 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
3596 .pNext = &ext_props,
3598 VkPhysicalDeviceImageDrmFormatModifierInfoEXT props_drm_mod = {
3599 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
3600 .drmFormatModifier = ext_img_mod_spec.drmFormatModifier,
3601 .pQueueFamilyIndices = create_info.pQueueFamilyIndices,
3602 .queueFamilyIndexCount = create_info.queueFamilyIndexCount,
3603 .sharingMode = create_info.sharingMode,
3605 VkPhysicalDeviceExternalImageFormatInfo props_ext = {
3606 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
3607 .pNext = &props_drm_mod,
3608 .handleType = ext_img_spec.handleTypes,
3610 VkPhysicalDeviceImageFormatInfo2 fmt_props;
3613 create_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT |
3614 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3616 create_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT |
3617 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3619 fmt_props = (VkPhysicalDeviceImageFormatInfo2) {
3620 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3621 .pNext = &props_ext,
3622 .format = create_info.format,
3623 .type = create_info.imageType,
3624 .tiling = create_info.tiling,
3625 .usage = create_info.usage,
3626 .flags = create_info.flags,
3630 ret = vk->GetPhysicalDeviceImageFormatProperties2(hwctx->phys_dev,
3631 &fmt_props, &props_ret);
3632 if (ret != VK_SUCCESS) {
3640 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
3641 hwfc->sw_format,
src->width,
src->height,
i);
3644 for (
int j = 0; j <
planes; j++) {
3645 ext_img_layouts[j].offset =
desc->layers[
i].planes[j].offset;
3646 ext_img_layouts[j].rowPitch =
desc->layers[
i].planes[j].pitch;
3647 ext_img_layouts[j].size = 0;
3648 ext_img_layouts[j].arrayPitch = 0;
3649 ext_img_layouts[j].depthPitch = 0;
3653 ret = vk->CreateImage(hwctx->act_dev, &create_info,
3654 hwctx->alloc, &
f->img[
i]);
3655 if (ret != VK_SUCCESS) {
3662 ret = vk->CreateSemaphore(hwctx->act_dev, &sem_spawn,
3663 hwctx->alloc, &
f->sem[
i]);
3664 if (ret != VK_SUCCESS) {
3671 f->queue_family[
i] = VK_QUEUE_FAMILY_EXTERNAL;
3672 f->layout[
i] = create_info.initialLayout;
3674 f->sem_value[
i] = 0;
3677 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3679 VkImageMemoryRequirementsInfo2 req_desc = {
3680 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
3683 VkMemoryDedicatedRequirements ded_req = {
3684 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
3686 VkMemoryRequirements2 req2 = {
3687 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3692 VkMemoryFdPropertiesKHR fdmp = {
3693 .sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR,
3699 VkImportMemoryFdInfoKHR idesc = {
3700 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
3701 .fd = dup(
desc->objects[
desc->layers[
i].planes[0].object_index].fd),
3702 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3704 VkMemoryDedicatedAllocateInfo ded_alloc = {
3705 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
3707 .image = req_desc.image,
3711 ret = vk->GetMemoryFdPropertiesKHR(hwctx->act_dev,
3712 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3714 if (ret != VK_SUCCESS) {
3722 vk->GetImageMemoryRequirements2(hwctx->act_dev, &req_desc, &req2);
3725 req2.memoryRequirements.memoryTypeBits = fdmp.memoryTypeBits;
3728 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
3729 (ded_req.prefersDedicatedAllocation ||
3730 ded_req.requiresDedicatedAllocation) ?
3731 &ded_alloc : ded_alloc.pNext,
3732 &
f->flags, &
f->mem[
i]);
3738 f->size[
i] = req2.memoryRequirements.size;
3741 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3743 for (
int j = 0; j <
planes; j++) {
3744 VkImageAspectFlagBits aspect = j == 0 ? VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT :
3745 j == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3746 VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
3748 plane_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO;
3750 plane_info[bind_counts].planeAspect = aspect;
3752 bind_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
3754 bind_info[bind_counts].image =
f->img[
i];
3755 bind_info[bind_counts].memory =
f->mem[
i];
3758 bind_info[bind_counts].memoryOffset = 0;
3765 ret = vk->BindImageMemory2(hwctx->act_dev, bind_counts, bind_info);
3766 if (ret != VK_SUCCESS) {
3794#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
3796 VkCommandBuffer cmd_buf;
3802 for (
int i = 0;
i <
desc->nb_objects;
i++) {
3803 VkSemaphoreTypeCreateInfo sem_type_info = {
3804 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3805 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
3807 VkSemaphoreCreateInfo sem_spawn = {
3808 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3809 .pNext = &sem_type_info,
3811 VkImportSemaphoreFdInfoKHR import_info;
3812 struct dma_buf_export_sync_file implicit_fd_info = {
3813 .flags = DMA_BUF_SYNC_READ,
3817 if (ioctl(
desc->objects[
i].fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE,
3818 &implicit_fd_info)) {
3823 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3827 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3828 hwctx->
alloc, &drm_sync_sem[
i]);
3829 if (ret != VK_SUCCESS) {
3834 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3838 import_info = (VkImportSemaphoreFdInfoKHR) {
3839 .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
3840 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
3841 .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
3842 .semaphore = drm_sync_sem[
i],
3843 .fd = implicit_fd_info.fd,
3846 ret = vk->ImportSemaphoreFdKHR(hwctx->
act_dev, &import_info);
3847 if (ret != VK_SUCCESS) {
3852 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3858 cmd_buf = exec->
buf;
3862 for (
int i = 0;
i <
desc->nb_objects;
i++)
3863 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3869 drm_sync_sem,
desc->nb_objects,
3870 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 1);
3873 VK_PIPELINE_STAGE_2_NONE,
3874 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
3881 VK_PIPELINE_STAGE_2_NONE,
3882 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
3884 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT : 0x0) |
3886 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT : 0x0),
3887 VK_IMAGE_LAYOUT_GENERAL,
3888 p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED :
p->img_qfs[0]);
3890 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
3891 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
3892 .pImageMemoryBarriers = img_bar,
3893 .imageMemoryBarrierCount = nb_img_bar,
3904 "image may be corrupted.\n");
3920 if ((err = vulkan_map_from_drm_frame_desc(hwfc, &
f,
src,
flags)))
3924 dst->data[0] = (uint8_t *)
f;
3926 dst->height =
src->height;
3929 &vulkan_unmap_from_drm,
f);
3933 err = vulkan_map_from_drm_frame_sync(hwfc,
dst,
desc,
flags);
3956 VASurfaceID surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
3962 vaSyncSurface(vaapi_ctx->
display, surface_id);
3970 err = vulkan_map_from_drm(dst_fc,
dst,
tmp,
flags);
3987 VkDeviceMemory mem,
size_t size)
3995 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3996 .type = IsWindows8OrGreater()
3997 ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
3998 : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT,
4001 VkMemoryGetWin32HandleInfoKHR export_info = {
4002 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
4004 .handleType = IsWindows8OrGreater()
4005 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
4006 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
4009 ret = vk->GetMemoryWin32HandleKHR(hwctx->
act_dev, &export_info,
4010 &ext_desc.handle.win32.handle);
4011 if (ret != VK_SUCCESS) {
4016 dst_int->ext_mem_handle[idx] = ext_desc.handle.win32.handle;
4018 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
4019 .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
4022 VkMemoryGetFdInfoKHR export_info = {
4023 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
4025 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
4028 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
4029 &ext_desc.handle.fd);
4030 if (ret != VK_SUCCESS) {
4037 ret =
CHECK_CU(cu->cuImportExternalMemory(&dst_int->ext_mem[idx], &ext_desc));
4040 close(ext_desc.handle.fd);
4059 VkSemaphoreGetWin32HandleInfoKHR sem_export = {
4060 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
4062 .handleType = IsWindows8OrGreater()
4063 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
4064 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
4066 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
4070 VkSemaphoreGetFdInfoKHR sem_export = {
4071 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
4073 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
4075 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
4081 ret = vk->GetSemaphoreWin32HandleKHR(hwctx->
act_dev, &sem_export,
4082 &ext_sem_desc.handle.win32.handle);
4084 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &sem_export,
4085 &ext_sem_desc.handle.fd);
4087 if (ret != VK_SUCCESS) {
4093 dst_int->ext_sem_handle[idx] = ext_sem_desc.handle.win32.handle;
4096 ret =
CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[idx],
4100 close(ext_sem_desc.handle.fd);
4128 CudaFunctions *cu = cu_internal->
cuda_dl;
4129 CUarray_format cufmt =
desc->comp[0].depth > 8 ? CU_AD_FORMAT_UNSIGNED_INT16 :
4130 CU_AD_FORMAT_UNSIGNED_INT8;
4131 const int elem_size = 1 + (
desc->comp[0].depth > 8);
4134 dst_int = dst_f->internal;
4136 if (!dst_int->cuda_fc_ref) {
4140 if (!dst_int->cuda_fc_ref)
4144 for (
int i = 0;
i < nb_images;
i++) {
4145 err = export_mem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
4146 dst_f->mem[
i], dst_f->size[
i]);
4150 err = export_sem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
4156 if (nb_images !=
planes) {
4160 if (
desc->comp[
i].step / elem_size > 1) {
4162 "Cannot map a multiplane Vulkan image (%d image(s) "
4163 "for %d plane(s)) to CUDA; create the Vulkan device "
4164 "with the disable_multiplane=1 option (one image per "
4165 "plane) for CUDA interop.\n", nb_images,
planes);
4170 VkImageSubresource subres = {
4171 .aspectMask =
i == 2 ? VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT :
4172 i == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
4173 VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT
4175 VkSubresourceLayout
layout = { 0 };
4176 vk->GetImageSubresourceLayout(hwctx->
act_dev, dst_f->img[
FFMIN(
i, nb_images - 1)],
4183 CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = {
4188 .NumChannels =
desc->comp[
i].step / elem_size,
4196 tex_desc.arrayDesc.Width = p_w;
4197 tex_desc.arrayDesc.Height = p_h;
4199 ret =
CHECK_CU(cu->cuExternalMemoryGetMappedMipmappedArray(&dst_int->cu_mma[
i],
4200 dst_int->ext_mem[
FFMIN(
i, nb_images - 1)],
4207 ret =
CHECK_CU(cu->cuMipmappedArrayGetLevel(&dst_int->cu_array[
i],
4208 dst_int->cu_mma[
i], 0));
4241 CudaFunctions *cu = cu_internal->
cuda_dl;
4252 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
4256 err = vulkan_export_to_cuda(hwfc,
src->hw_frames_ctx,
dst);
4262 dst_int = dst_f->internal;
4264 for (
int i = 0;
i < nb_images;
i++) {
4265 s_w_par[
i].params.fence.value = dst_f->sem_value[
i] + 0;
4266 s_s_par[
i].params.fence.value = dst_f->sem_value[
i] + 1;
4269 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
4270 nb_images, cuda_dev->stream));
4275 CUDA_MEMCPY2D cpy = {
4276 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
4277 .srcDevice = (CUdeviceptr)
src->data[
i],
4278 .srcPitch =
src->linesize[
i],
4281 .dstMemoryType = CU_MEMORYTYPE_ARRAY,
4282 .dstArray = dst_int->cu_array[
i],
4288 cpy.WidthInBytes = p_w *
desc->comp[
i].step;
4291 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
4296 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
4297 nb_images, cuda_dev->stream));
4301 for (
int i = 0;
i < nb_images;
i++)
4302 dst_f->sem_value[
i]++;
4323 switch (
src->format) {
4328 return vulkan_map_from_vaapi(hwfc,
dst,
src,
flags);
4334 return vulkan_map_from_drm(hwfc,
dst,
src,
flags);
4344typedef struct VulkanDRMMapping {
4345 AVDRMFrameDescriptor drm_desc;
4363static inline uint32_t vulkan_fmt_to_drm(
VkFormat vkfmt)
4366 if (vulkan_drm_format_map[
i].vk_format == vkfmt)
4367 return vulkan_drm_format_map[
i].drm_fourcc;
4368 return DRM_FORMAT_INVALID;
4371#define MAX_MEMORY_PLANES 4
4372static VkImageAspectFlags plane_index_to_aspect(
int plane) {
4373 if (plane == 0)
return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
4374 if (plane == 1)
return VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT;
4375 if (plane == 2)
return VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
4376 if (plane == 3)
return VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT;
4379 return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
4382#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
4392 if (
f->internal->drm_sync_sem == VK_NULL_HANDLE) {
4393 VkExportSemaphoreCreateInfo exp_info = {
4394 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
4395 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
4397 VkSemaphoreTypeCreateInfo type_info = {
4398 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
4400 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
4402 VkSemaphoreCreateInfo sem_create = {
4403 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
4404 .pNext = &type_info,
4406 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_create, hwctx->
alloc,
4407 &
f->internal->drm_sync_sem);
4408 if (ret != VK_SUCCESS) {
4420 for (
int i = 0;
i < nb_sems;
i++)
4423 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
4425 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 0);
4427 VkSemaphoreGetFdInfoKHR get_fd_info = {
4428 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
4429 .semaphore =
f->internal->drm_sync_sem,
4430 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
4432 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &get_fd_info, &sync_fd);
4433 if (ret != VK_SUCCESS) {
4435 "Failed to get sync fd from DRM map export semaphore: %s\n",
4458 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
4459 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
4461 const int nb_sems = nb_images;
4462 int free_drm_desc_on_err = 1;
4473#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
4475 f->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
4476 vk->GetSemaphoreFdKHR && vk->CreateSemaphore) {
4477 err = vulkan_drm_export_sync_fd(hwfc,
f, fp, nb_sems);
4486 VkSemaphoreWaitInfo wait_info = {
4487 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
4489 .semaphoreCount = nb_sems,
4490 .pSemaphores =
f->sem,
4491 .pValues =
f->sem_value,
4493 vk->WaitSemaphores(hwctx->
act_dev, &wait_info, UINT64_MAX);
4501 free_drm_desc_on_err = 0;
4503 ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->
act_dev,
f->img[0],
4505 if (ret != VK_SUCCESS) {
4511 for (
int i = 0; (
i <
planes) && (
f->mem[
i]);
i++) {
4512 VkMemoryGetFdInfoKHR export_info = {
4513 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
4514 .memory =
f->mem[
i],
4515 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
4518 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
4520 if (ret != VK_SUCCESS) {
4526#if HAVE_LINUX_DMA_BUF_H && defined(DMA_BUF_IOCTL_IMPORT_SYNC_FILE)
4528 int dup_fd = dup(sync_fd);
4530 struct dma_buf_import_sync_file import_info = {
4531 .flags = DMA_BUF_SYNC_WRITE,
4534 if (ioctl(drm_desc->
objects[
i].
fd, DMA_BUF_IOCTL_IMPORT_SYNC_FILE, &import_info) < 0)
4553 drm_desc->
layers[
i].
format = vulkan_fmt_to_drm(plane_vkfmt);
4563 VkSubresourceLayout
layout;
4564 int aspect_plane = (nb_images == 1) ?
i : j;
4565 VkImageSubresource sub = {
4566 .aspectMask = plane_index_to_aspect(aspect_plane),
4583 if (
f->tiling == VK_IMAGE_TILING_OPTIMAL)
4589 dst->height =
src->height;
4590 dst->data[0] = (uint8_t *)drm_desc;
4603 if (free_drm_desc_on_err)
4643 switch (
dst->format) {
4653 return vulkan_map_to_vaapi(hwfc,
dst,
src,
flags);
4665 AVFrame *swf, VkBufferImageCopy *region,
4674 region[
i].bufferRowLength,
4678 region[
i].imageExtent.height);
4681 if (err != VK_SUCCESS) {
4688 if (err != VK_SUCCESS) {
4698 region[
i].bufferRowLength,
4700 region[
i].imageExtent.height);
4707 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4714 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4715 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4717 size_t buf_offset = 0;
4721 region[
i] = (VkBufferImageCopy) {
4722 .bufferOffset = buf_offset,
4724 p->props.properties.limits.optimalBufferCopyRowPitchAlignment),
4725 .bufferImageHeight = p_h,
4726 .imageSubresource.layerCount = 1,
4727 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4731 buf_offset +=
FFALIGN(p_h*region[
i].bufferRowLength,
4732 p->props.properties.limits.optimalBufferCopyOffsetAlignment);
4737 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
4738 p->vkctx.host_cached_flag);
4746 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4753 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4754 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4763 while (swf->
buf[nb_src_bufs])
4767 if (nb_src_bufs == 1) {
4769 swf->
data[0], VK_WHOLE_SIZE, swf->
buf[0],
4776 region[
i].bufferOffset =
dst[0]->virtual_offset +
4778 }
else if (nb_src_bufs ==
planes) {
4781 swf->
data[
i], VK_WHOLE_SIZE,
4782 swf->
buf[
i], buf_usage);
4787 region[
i].bufferOffset =
dst[
i]->virtual_offset;
4797 for (
int i = 0;
i < (*nb_bufs);
i++)
4818 int nb_layout_ch = 0;
4822 for (
int i = 0;
i < nb_images;
i++) {
4824 for (
int j = 0; j < p->vkctx.host_image_props.copySrcLayoutCount; j++) {
4825 if (hwf_vk->
layout[
i] == p->vkctx.host_image_props.pCopySrcLayouts[j]) {
4835 layout_ch_info[nb_layout_ch] = (VkHostImageLayoutTransitionInfoEXT) {
4836 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT,
4837 .image = hwf_vk->
img[
i],
4838 .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
4839 .newLayout = VK_IMAGE_LAYOUT_GENERAL,
4840 .subresourceRange = {
4841 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4847 hwf_vk->
layout[
i] = layout_ch_info[nb_layout_ch].newLayout;
4852 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
4853 .pSemaphores = hwf_vk->
sem,
4855 .semaphoreCount = nb_images,
4861 vk->TransitionImageLayoutEXT(hwctx->
act_dev,
4862 nb_layout_ch, layout_ch_info);
4865 VkMemoryToImageCopyEXT region_info = {
4866 .sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT,
4867 .imageSubresource = {
4871 VkCopyMemoryToImageInfoEXT copy_info = {
4872 .sType = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT,
4874 .pRegions = ®ion_info,
4877 int img_idx =
FFMIN(
i, (nb_images - 1));
4881 region_info.pHostPointer = swf->
data[
i];
4882 region_info.memoryRowLength = swf->
linesize[
i] /
desc->comp[
i].step;
4884 region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 };
4885 copy_info.dstImage = hwf_vk->
img[img_idx];
4886 copy_info.dstImageLayout = hwf_vk->
layout[img_idx];
4888 vk->CopyMemoryToImageEXT(hwctx->
act_dev, ©_info);
4891 VkImageToMemoryCopyEXT region_info = {
4892 .sType = VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT,
4893 .imageSubresource = {
4897 VkCopyImageToMemoryInfoEXT copy_info = {
4898 .sType = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT,
4900 .pRegions = ®ion_info,
4903 int img_idx =
FFMIN(
i, (nb_images - 1));
4907 region_info.pHostPointer = swf->
data[
i];
4908 region_info.memoryRowLength = swf->
linesize[
i] /
desc->comp[
i].step;
4910 region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 };
4911 copy_info.srcImage = hwf_vk->
img[img_idx];
4912 copy_info.srcImageLayout = hwf_vk->
layout[img_idx];
4914 vk->CopyImageToMemoryEXT(hwctx->
act_dev, ©_info);
4933 int host_mapped = 0;
4948 VkCommandBuffer cmd_buf;
4960 int host_copy = hwctx->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
4963 if (!upload && host_copy) {
4964 for (
int i = 0;
i < nb_images;
i++) {
4966 for (
int j = 0; j < p->vkctx.host_image_props.copySrcLayoutCount; j++) {
4967 if (hwf_vk->
layout[
i] == p->vkctx.host_image_props.pCopySrcLayouts[j]) {
4987 region[
i] = (VkBufferImageCopy) {
4990 .bufferImageHeight = p_h,
4991 .imageSubresource.layerCount = 1,
4992 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
5018 cmd_buf = exec->
buf;
5026 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
5027 VK_PIPELINE_STAGE_2_TRANSFER_BIT);
5045 for (
int i = 0;
i < nb_bufs;
i++)
5050 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
5051 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,
5052 upload ? VK_ACCESS_TRANSFER_WRITE_BIT :
5053 VK_ACCESS_TRANSFER_READ_BIT,
5054 upload ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL :
5055 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5056 p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED : p->img_qfs[0]);
5058 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
5059 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
5060 .pImageMemoryBarriers = img_bar,
5061 .imageMemoryBarrierCount = nb_img_bar,
5065 int buf_idx =
FFMIN(
i, (nb_bufs - 1));
5066 int img_idx =
FFMIN(
i, (nb_images - 1));
5069 uint32_t orig_stride = region[
i].bufferRowLength;
5070 region[
i].bufferRowLength /=
desc->comp[
i].step;
5074 vk->CmdCopyBufferToImage(cmd_buf, vkbuf->
buf,
5075 hwf_vk->
img[img_idx],
5076 img_bar[img_idx].newLayout,
5079 vk->CmdCopyImageToBuffer(cmd_buf, hwf_vk->
img[img_idx],
5080 img_bar[img_idx].newLayout,
5084 region[
i].bufferRowLength = orig_stride;
5088 if (err >= 0 && !upload) {
5095 for (
int i = 0;
i < nb_bufs;
i++)
5106 switch (
src->format) {
5116 return vulkan_transfer_data_from_cuda(hwfc,
dst,
src);
5120 if (
src->hw_frames_ctx)
5145 CudaFunctions *cu = cu_internal->
cuda_dl;
5156 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
5160 err = vulkan_export_to_cuda(hwfc,
dst->hw_frames_ctx,
src);
5166 dst_int = dst_f->internal;
5168 for (
int i = 0;
i < nb_images;
i++) {
5169 s_w_par[
i].params.fence.value = dst_f->sem_value[
i] + 0;
5170 s_s_par[
i].params.fence.value = dst_f->sem_value[
i] + 1;
5173 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
5174 nb_images, cuda_dev->stream));
5179 CUDA_MEMCPY2D cpy = {
5180 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
5181 .dstDevice = (CUdeviceptr)
dst->data[
i],
5182 .dstPitch =
dst->linesize[
i],
5185 .srcMemoryType = CU_MEMORYTYPE_ARRAY,
5186 .srcArray = dst_int->cu_array[
i],
5192 cpy.WidthInBytes =
w *
desc->comp[
i].step;
5195 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
5200 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
5201 nb_images, cuda_dev->stream));
5205 for (
int i = 0;
i < nb_images;
i++)
5206 dst_f->sem_value[
i]++;
5227 switch (
dst->format) {
5237 return vulkan_transfer_data_to_cuda(hwfc,
dst,
src);
5241 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.