21#define VK_NO_PROTOTYPES
22#define VK_ENABLE_BETA_EXTENSIONS
26#include <versionhelpers.h>
53#include <va/va_drmcommon.h>
56#include <sys/sysmacros.h>
60#include <drm_fourcc.h>
64#if HAVE_LINUX_DMA_BUF_H
66#include <linux/dma-buf.h>
72#define CHECK_CU(x) FF_CUDA_CHECK_DL(cuda_cu, cu, x)
86#ifdef VK_EXT_shader_long_vector
87 VkPhysicalDeviceShaderLongVectorFeaturesEXT long_vector;
90#ifdef VK_EXT_shader_replicated_composites
91 VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT replicated_composites;
94#ifdef VK_EXT_zero_initialize_device_memory
95 VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT zero_initialize;
98#ifdef VK_KHR_shader_expect_assume
99 VkPhysicalDeviceShaderExpectAssumeFeaturesKHR expect_assume;
102#ifdef VK_KHR_shader_maximal_reconvergence
103 VkPhysicalDeviceShaderMaximalReconvergenceFeaturesKHR maximal_reconvergence;
106#ifdef VK_KHR_maintenance9
107 VkPhysicalDeviceMaintenance9FeaturesKHR maintenance_9;
109#ifdef VK_KHR_unified_image_layouts
110 VkPhysicalDeviceUnifiedImageLayoutsFeaturesKHR unified_layouts;
114#ifdef VK_KHR_video_maintenance2
115 VkPhysicalDeviceVideoMaintenance2FeaturesKHR video_maintenance_2;
117#ifdef VK_KHR_video_decode_vp9
118 VkPhysicalDeviceVideoDecodeVP9FeaturesKHR vp9_decode;
120#ifdef VK_KHR_video_encode_av1
121 VkPhysicalDeviceVideoEncodeAV1FeaturesKHR av1_encode;
128#ifdef VK_KHR_shader_relaxed_extended_instruction
129 VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR relaxed_extended_instruction;
132#ifdef VK_KHR_internally_synchronized_queues
133 VkPhysicalDeviceInternallySynchronizedQueuesFeaturesKHR internal_queue_sync;
153 VkPhysicalDeviceExternalMemoryHostPropertiesEXT
hprops;
241 feats->
device = (VkPhysicalDeviceFeatures2) {
242 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
246 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES);
248 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES);
250 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES);
253 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES);
255 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES_KHR);
257 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT);
259#ifdef VK_EXT_shader_long_vector
261 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_LONG_VECTOR_FEATURES_EXT);
264#ifdef VK_EXT_shader_replicated_composites
266 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_REPLICATED_COMPOSITES_FEATURES_EXT);
269#ifdef VK_EXT_zero_initialize_device_memory
271 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_DEVICE_MEMORY_FEATURES_EXT);
274#ifdef VK_KHR_shader_expect_assume
276 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES_KHR);
279#ifdef VK_KHR_shader_maximal_reconvergence
281 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MAXIMAL_RECONVERGENCE_FEATURES_KHR);
284#ifdef VK_KHR_maintenance9
286 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_9_FEATURES_KHR);
288#ifdef VK_KHR_unified_image_layouts
290 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFIED_IMAGE_LAYOUTS_FEATURES_KHR);
294 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR);
295#ifdef VK_KHR_video_maintenance2
297 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR);
299#ifdef VK_KHR_video_decode_vp9
301 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR);
303#ifdef VK_KHR_video_encode_av1
305 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR);
309 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);
311 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR);
313 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT);
315 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR);
317#ifdef VK_KHR_shader_relaxed_extended_instruction
319 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR);
322#ifdef VK_KHR_internally_synchronized_queues
324 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INTERNALLY_SYNCHRONIZED_QUEUES_FEATURES_KHR);
331#define COPY_VAL(VAL) \
333 dst->VAL = src->VAL; \
336 COPY_VAL(device.features.shaderImageGatherExtended);
337 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
338 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
339 COPY_VAL(device.features.fragmentStoresAndAtomics);
340 COPY_VAL(device.features.vertexPipelineStoresAndAtomics);
341 COPY_VAL(device.features.shaderInt64);
342 COPY_VAL(device.features.shaderInt16);
343 COPY_VAL(device.features.shaderFloat64);
344 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
345 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
347 COPY_VAL(vulkan_1_1.samplerYcbcrConversion);
348 COPY_VAL(vulkan_1_1.storagePushConstant16);
349 COPY_VAL(vulkan_1_1.storageBuffer16BitAccess);
350 COPY_VAL(vulkan_1_1.uniformAndStorageBuffer16BitAccess);
352 COPY_VAL(vulkan_1_2.timelineSemaphore);
353 COPY_VAL(vulkan_1_2.scalarBlockLayout);
354 COPY_VAL(vulkan_1_2.bufferDeviceAddress);
355 COPY_VAL(vulkan_1_2.hostQueryReset);
356 COPY_VAL(vulkan_1_2.storagePushConstant8);
358 COPY_VAL(vulkan_1_2.storageBuffer8BitAccess);
359 COPY_VAL(vulkan_1_2.uniformAndStorageBuffer8BitAccess);
361 COPY_VAL(vulkan_1_2.shaderBufferInt64Atomics);
362 COPY_VAL(vulkan_1_2.shaderSharedInt64Atomics);
363 COPY_VAL(vulkan_1_2.vulkanMemoryModel);
364 COPY_VAL(vulkan_1_2.vulkanMemoryModelDeviceScope);
365 COPY_VAL(vulkan_1_2.vulkanMemoryModelAvailabilityVisibilityChains);
366 COPY_VAL(vulkan_1_2.uniformBufferStandardLayout);
367 COPY_VAL(vulkan_1_2.runtimeDescriptorArray);
368 COPY_VAL(vulkan_1_2.shaderSubgroupExtendedTypes);
369 COPY_VAL(vulkan_1_2.shaderUniformBufferArrayNonUniformIndexing);
370 COPY_VAL(vulkan_1_2.shaderSampledImageArrayNonUniformIndexing);
371 COPY_VAL(vulkan_1_2.shaderStorageBufferArrayNonUniformIndexing);
372 COPY_VAL(vulkan_1_2.shaderStorageImageArrayNonUniformIndexing);
374 COPY_VAL(vulkan_1_3.dynamicRendering);
376 COPY_VAL(vulkan_1_3.synchronization2);
377 COPY_VAL(vulkan_1_3.computeFullSubgroups);
378 COPY_VAL(vulkan_1_3.subgroupSizeControl);
379 COPY_VAL(vulkan_1_3.shaderZeroInitializeWorkgroupMemory);
380 COPY_VAL(vulkan_1_3.dynamicRendering);
382 COPY_VAL(timeline_semaphore.timelineSemaphore);
383 COPY_VAL(subgroup_rotate.shaderSubgroupRotate);
384 COPY_VAL(host_image_copy.hostImageCopy);
386#ifdef VK_EXT_shader_long_vector
390#ifdef VK_EXT_shader_replicated_composites
391 COPY_VAL(replicated_composites.shaderReplicatedComposites);
394#ifdef VK_EXT_zero_initialize_device_memory
395 COPY_VAL(zero_initialize.zeroInitializeDeviceMemory);
398 COPY_VAL(video_maintenance_1.videoMaintenance1);
399#ifdef VK_KHR_video_maintenance2
400 COPY_VAL(video_maintenance_2.videoMaintenance2);
403#ifdef VK_KHR_video_decode_vp9
404 COPY_VAL(vp9_decode.videoDecodeVP9);
407#ifdef VK_KHR_video_encode_av1
408 COPY_VAL(av1_encode.videoEncodeAV1);
411 COPY_VAL(shader_object.shaderObject);
413 COPY_VAL(cooperative_matrix.cooperativeMatrix);
415 COPY_VAL(atomic_float.shaderBufferFloat32Atomics);
416 COPY_VAL(atomic_float.shaderBufferFloat32AtomicAdd);
418 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayout);
419 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayoutScalarBlockLayout);
420 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayout8BitAccess);
421 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayout16BitAccess);
423#ifdef VK_KHR_shader_relaxed_extended_instruction
424 COPY_VAL(relaxed_extended_instruction.shaderRelaxedExtendedInstruction);
427#ifdef VK_KHR_shader_expect_assume
428 COPY_VAL(expect_assume.shaderExpectAssume);
431#ifdef VK_KHR_shader_maximal_reconvergence
432 COPY_VAL(maximal_reconvergence.shaderMaximalReconvergence);
435#ifdef VK_KHR_maintenance9
436 COPY_VAL(maintenance_9.maintenance9);
438#ifdef VK_KHR_unified_image_layouts
439 COPY_VAL(unified_layouts.unifiedImageLayouts);
440 COPY_VAL(unified_layouts.unifiedImageLayoutsVideo);
443#ifdef VK_KHR_internally_synchronized_queues
444 COPY_VAL(internal_queue_sync.internallySynchronizedQueues);
450#define ASPECT_2PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT)
451#define ASPECT_3PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)
463 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_GRAY8, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8_UNORM } },
464 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
465 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY12, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
466 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY14, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
467 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
468 { VK_FORMAT_R32_UINT,
AV_PIX_FMT_GRAY32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_UINT } },
469 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GRAYF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_SFLOAT } },
472 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_BGRA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
473 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGBA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
474 { VK_FORMAT_R8G8B8_UNORM,
AV_PIX_FMT_RGB24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8_UNORM } },
475 { VK_FORMAT_B8G8R8_UNORM,
AV_PIX_FMT_BGR24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8_UNORM } },
476 { VK_FORMAT_R16G16B16_UNORM,
AV_PIX_FMT_RGB48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16_UNORM } },
477 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_RGBA64, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
478 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_BGR0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
479 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGB0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
480 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_X2RGB10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
481 { VK_FORMAT_A2B10G10R10_UNORM_PACK32,
AV_PIX_FMT_X2BGR10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2B10G10R10_UNORM_PACK32 } },
482 { VK_FORMAT_R32G32B32_SFLOAT,
AV_PIX_FMT_RGBF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_SFLOAT } },
483 { VK_FORMAT_R16G16B16A16_SFLOAT,
AV_PIX_FMT_RGBAF16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_SFLOAT } },
484 { VK_FORMAT_R32G32B32A32_SFLOAT,
AV_PIX_FMT_RGBAF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_SFLOAT } },
485 { VK_FORMAT_R32G32B32_UINT,
AV_PIX_FMT_RGB96, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_UINT } },
486 { VK_FORMAT_R32G32B32A32_UINT,
AV_PIX_FMT_RGBA128, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_UINT } },
489 { 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 } },
490 { 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 } },
491 { 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 } },
492 { 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 } },
493 { 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 } },
494 { 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 } },
495 { 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 } },
498 { 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 } },
499 { 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 } },
500 { 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 } },
501 { 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 } },
502 { 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 } },
503 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GBRAPF16, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } },
504 { 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 } },
505 { 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 } },
512 { 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 } },
513 { 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 } },
518 { 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 } },
519 { 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 } },
524 { 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 } },
525 { 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 } },
543 { VK_FORMAT_G8B8G8R8_422_UNORM,
AV_PIX_FMT_YUYV422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
544 { VK_FORMAT_B8G8R8G8_422_UNORM,
AV_PIX_FMT_UYVY422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
545 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
AV_PIX_FMT_Y210, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
546 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
AV_PIX_FMT_Y212, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
547 { VK_FORMAT_G16B16G16R16_422_UNORM,
AV_PIX_FMT_Y216, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
550 { 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 } },
551 { 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 } },
552 { 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 } },
555 { 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 } },
556 { 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 } },
557 { 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 } },
558 { 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 } },
561 { 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 } },
562 { 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 } },
563 { 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 } },
564 { 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 } },
567 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_XV30, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
568 { VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
AV_PIX_FMT_XV36, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
569 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_XV48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
590 VkImageTiling tiling,
593 VkImageAspectFlags *
aspect,
594 VkImageUsageFlags *supported_usage,
595 int disable_multiplane,
int need_storage)
601 const VkFormatFeatureFlagBits2 basic_flags = VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
602 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
603 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
607 VkFormatProperties3 fprops = {
608 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3,
610 VkFormatProperties2 prop = {
611 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
614 VkFormatFeatureFlagBits2 feats_primary, feats_secondary;
615 int basics_primary = 0, basics_secondary = 0;
616 int storage_primary = 0, storage_secondary = 0;
618 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
622 feats_primary = tiling == VK_IMAGE_TILING_LINEAR ?
623 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
624 basics_primary = (feats_primary & basic_flags) == basic_flags;
625 storage_primary = !!(feats_primary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
628 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
631 feats_secondary = tiling == VK_IMAGE_TILING_LINEAR ?
632 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
633 basics_secondary = (feats_secondary & basic_flags) == basic_flags;
634 storage_secondary = !!(feats_secondary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
636 basics_secondary = basics_primary;
637 storage_secondary = storage_primary;
640 if (basics_primary &&
642 (!need_storage || (need_storage && (storage_primary | storage_secondary)))) {
657 ((need_storage && (storage_primary | storage_secondary)) ?
658 VK_IMAGE_USAGE_STORAGE_BIT : 0);
660 }
else if (basics_secondary &&
661 (!need_storage || (need_storage && storage_secondary))) {
682#if CONFIG_VULKAN_STATIC
683VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance,
692#if CONFIG_VULKAN_STATIC
695 static const char *lib_names[] = {
698#elif defined(__APPLE__)
709 p->libvulkan = dlopen(lib_names[
i], RTLD_NOW | RTLD_LOCAL);
719 hwctx->
get_proc_addr = (PFN_vkGetInstanceProcAddr)dlsym(p->libvulkan,
"vkGetInstanceProcAddr");
748#ifdef VK_KHR_shader_relaxed_extended_instruction
751#ifdef VK_EXT_shader_long_vector
754#ifdef VK_EXT_shader_replicated_composites
757#ifdef VK_EXT_zero_initialize_device_memory
760#ifdef VK_KHR_shader_expect_assume
763#ifdef VK_KHR_shader_maximal_reconvergence
766#ifdef VK_KHR_maintenance9
769#ifdef VK_KHR_unified_image_layouts
773#ifdef VK_KHR_video_maintenance2
776#ifdef VK_KHR_internally_synchronized_queues
799#ifdef VK_KHR_video_decode_vp9
802#ifdef VK_KHR_video_encode_av1
838 VkDebugUtilsMessageTypeFlagsEXT messageType,
839 const VkDebugUtilsMessengerCallbackDataEXT *
data,
846 switch (
data->messageIdNumber) {
855 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: l =
AV_LOG_VERBOSE;
break;
856 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: l =
AV_LOG_INFO;
break;
857 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: l =
AV_LOG_WARNING;
break;
858 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: l =
AV_LOG_ERROR;
break;
863 for (
int i = 0;
i <
data->cmdBufLabelCount;
i++)
869#define ADD_VAL_TO_LIST(list, count, val) \
871 list = av_realloc_array(list, ++count, sizeof(*list)); \
873 err = AVERROR(ENOMEM); \
876 list[count - 1] = av_strdup(val); \
877 if (!list[count - 1]) { \
878 err = AVERROR(ENOMEM); \
883#define RELEASE_PROPS(props, count) \
885 for (int i = 0; i < count; i++) \
886 av_free((void *)((props)[i])); \
887 av_free((void *)props); \
893 VkDeviceSize max_vram = 0, max_visible_vram = 0;
897 for (
int i = 0;
i < p->mprops.memoryTypeCount;
i++) {
898 const VkMemoryType
type = p->mprops.memoryTypes[
i];
899 const VkMemoryHeap heap = p->mprops.memoryHeaps[
type.heapIndex];
900 if (!(
type.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
902 max_vram =
FFMAX(max_vram, heap.size);
903 if (
type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
904 max_visible_vram =
FFMAX(max_visible_vram, heap.size);
907 return max_vram - max_visible_vram < 1024;
923 const char *
const **
dst, uint32_t *num,
927 const char **extension_names =
NULL;
931 int err = 0, found, extensions_found = 0;
934 int optional_exts_num;
935 uint32_t sup_ext_count;
936 char *user_exts_str =
NULL;
938 VkExtensionProperties *sup_ext;
948 if (!user_exts_str) {
953 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count,
NULL);
954 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
957 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count, sup_ext);
965 if (!user_exts_str) {
970 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
971 &sup_ext_count,
NULL);
972 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
975 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
976 &sup_ext_count, sup_ext);
979 for (
int i = 0;
i < optional_exts_num;
i++) {
980 tstr = optional_exts[
i].
name;
984 if (!strcmp(tstr, VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME) &&
992 (!strcmp(tstr, VK_EXT_SHADER_OBJECT_EXTENSION_NAME))) {
996 for (
int j = 0; j < sup_ext_count; j++) {
997 if (!strcmp(tstr, sup_ext[j].extensionName)) {
1006 p->vkctx.extensions |= optional_exts[
i].
flag;
1014 tstr = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
1016 for (
int j = 0; j < sup_ext_count; j++) {
1017 if (!strcmp(tstr, sup_ext[j].extensionName)) {
1033#ifdef VK_KHR_shader_relaxed_extended_instruction
1035 tstr = VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME;
1037 for (
int j = 0; j < sup_ext_count; j++) {
1038 if (!strcmp(tstr, sup_ext[j].extensionName)) {
1052 if (user_exts_str) {
1053 char *save, *token =
av_strtok(user_exts_str,
"+", &save);
1056 for (
int j = 0; j < sup_ext_count; j++) {
1057 if (!strcmp(token, sup_ext[j].extensionName)) {
1073 *
dst = extension_names;
1074 *num = extensions_found;
1088 const char *
const **
dst, uint32_t *num,
1095 static const char layer_standard_validation[] = {
"VK_LAYER_KHRONOS_validation" };
1096 int layer_standard_validation_found = 0;
1098 uint32_t sup_layer_count;
1099 VkLayerProperties *sup_layers;
1102 char *user_layers_str =
NULL;
1105 const char **enabled_layers =
NULL;
1106 uint32_t enabled_layers_count = 0;
1114 vk->EnumerateInstanceLayerProperties(&sup_layer_count,
NULL);
1115 sup_layers =
av_malloc_array(sup_layer_count,
sizeof(VkLayerProperties));
1118 vk->EnumerateInstanceLayerProperties(&sup_layer_count, sup_layers);
1121 for (
int i = 0;
i < sup_layer_count;
i++)
1125 if (!debug_opt && !user_layers)
1130 if (!strcmp(debug_opt->
value,
"printf")) {
1132 }
else if (!strcmp(debug_opt->
value,
"validate")) {
1134 }
else if (!strcmp(debug_opt->
value,
"practices")) {
1137 char *end_ptr =
NULL;
1138 int idx = strtol(debug_opt->
value, &end_ptr, 10);
1139 if (end_ptr == debug_opt->
value || end_ptr[0] !=
'\0' ||
1154 for (
int i = 0;
i < sup_layer_count;
i++) {
1155 if (!strcmp(layer_standard_validation, sup_layers[
i].layerName)) {
1157 layer_standard_validation);
1158 ADD_VAL_TO_LIST(enabled_layers, enabled_layers_count, layer_standard_validation);
1160 layer_standard_validation_found = 1;
1164 if (!layer_standard_validation_found) {
1166 "Validation Layer \"%s\" not supported\n", layer_standard_validation);
1177 if (!user_layers_str) {
1182 token =
av_strtok(user_layers_str,
"+", &save);
1187 if (!strcmp(layer_standard_validation, token) && layer_standard_validation_found) {
1193 for (
int j = 0; j < sup_layer_count; j++) {
1194 if (!strcmp(token, sup_layers[j].layerName)) {
1205 if (!strcmp(layer_standard_validation, token))
1209 "Layer \"%s\" not supported\n", token);
1226 *
dst = enabled_layers;
1227 *num = enabled_layers_count;
1242 VkApplicationInfo application_info = {
1243 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
1244 .pApplicationName =
"ffmpeg",
1248 .pEngineName =
"libavutil",
1249 .apiVersion = VK_API_VERSION_1_3,
1254 VkValidationFeaturesEXT validation_features = {
1255 .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
1257 VkInstanceCreateInfo inst_props = {
1258 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
1259 .pApplicationInfo = &application_info,
1275 &inst_props.enabledLayerCount, debug_mode);
1281 &inst_props.enabledExtensionCount, *debug_mode);
1289 static const VkValidationFeatureEnableEXT feat_list_validate[] = {
1290 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1291 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1292 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
1294 validation_features.pEnabledValidationFeatures = feat_list_validate;
1295 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_validate);
1296 inst_props.pNext = &validation_features;
1298 static const VkValidationFeatureEnableEXT feat_list_debug[] = {
1299 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1300 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1301 VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT,
1303 validation_features.pEnabledValidationFeatures = feat_list_debug;
1304 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_debug);
1305 inst_props.pNext = &validation_features;
1307 static const VkValidationFeatureEnableEXT feat_list_practices[] = {
1308 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1309 VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT,
1311 validation_features.pEnabledValidationFeatures = feat_list_practices;
1312 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_practices);
1313 inst_props.pNext = &validation_features;
1317 for (
int i = 0;
i < inst_props.enabledExtensionCount;
i++) {
1318 if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
1319 inst_props.ppEnabledExtensionNames[
i])) {
1320 inst_props.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
1327 ret = vk->CreateInstance(&inst_props, hwctx->
alloc, &hwctx->
inst);
1330 if (ret != VK_SUCCESS) {
1347 VkDebugUtilsMessengerCreateInfoEXT dbg = {
1348 .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
1349 .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
1350 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
1351 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
1352 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
1353 .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
1354 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
1355 VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
1360 vk->CreateDebugUtilsMessengerEXT(hwctx->
inst, &dbg,
1361 hwctx->
alloc, &p->debug_ctx);
1367 RELEASE_PROPS(inst_props.ppEnabledLayerNames, inst_props.enabledLayerCount);
1386 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
return "integrated";
1387 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
return "discrete";
1388 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
return "virtual";
1389 case VK_PHYSICAL_DEVICE_TYPE_CPU:
return "software";
1390 default:
return "unknown";
1397 int err = 0, choice = -1;
1403 VkPhysicalDevice *devices =
NULL;
1404 VkPhysicalDeviceIDProperties *idp =
NULL;
1405 VkPhysicalDeviceProperties2 *prop =
NULL;
1406 VkPhysicalDeviceDriverProperties *driver_prop =
NULL;
1407 VkPhysicalDeviceDrmPropertiesEXT *drm_prop =
NULL;
1409 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num,
NULL);
1410 if (ret != VK_SUCCESS || !num) {
1419 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num, devices);
1420 if (ret != VK_SUCCESS) {
1439 driver_prop =
av_calloc(num,
sizeof(*driver_prop));
1446 drm_prop =
av_calloc(num,
sizeof(*drm_prop));
1454 for (
int i = 0;
i < num;
i++) {
1456 drm_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT;
1457 driver_prop[
i].pNext = &drm_prop[
i];
1459 driver_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
1460 idp[
i].pNext = &driver_prop[
i];
1461 idp[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
1462 prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1463 prop[
i].pNext = &idp[
i];
1465 vk->GetPhysicalDeviceProperties2(devices[
i], &prop[
i]);
1467 prop[
i].properties.deviceName,
1469 prop[
i].properties.deviceID);
1473 for (
int i = 0;
i < num;
i++) {
1474 if (!strncmp(idp[
i].deviceUUID, select->
uuid, VK_UUID_SIZE)) {
1483 for (
int i = 0;
i < num;
i++) {
1484 if ((select->
drm_major == drm_prop[
i].primaryMajor &&
1485 select->
drm_minor == drm_prop[
i].primaryMinor) ||
1486 (select->
drm_major == drm_prop[
i].renderMajor &&
1487 select->
drm_minor == drm_prop[
i].renderMinor)) {
1496 }
else if (select->
name) {
1498 for (
int i = 0;
i < num;
i++) {
1499 if (strstr(prop[
i].properties.deviceName, select->
name)) {
1510 for (
int i = 0;
i < num;
i++) {
1511 if (select->
pci_device == prop[
i].properties.deviceID) {
1522 for (
int i = 0;
i < num;
i++) {
1523 if (select->
vendor_id == prop[
i].properties.vendorID) {
1533 if (select->
index < num) {
1534 choice = select->
index;
1546 choice, prop[choice].properties.deviceName,
1548 prop[choice].properties.deviceID);
1550 p->props = prop[choice];
1551 p->props.pNext =
NULL;
1552 p->dprops = driver_prop[choice];
1553 p->dprops.pNext =
NULL;
1567 VkQueueFlagBits
flags)
1570 uint32_t min_score = UINT32_MAX;
1572 for (
int i = 0;
i < num_qf;
i++) {
1573 VkQueueFlagBits qflags = qf[
i].queueFamilyProperties.queueFlags;
1576 if ((
flags & VK_QUEUE_TRANSFER_BIT) &&
1577 (qflags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)))
1578 qflags |= VK_QUEUE_TRANSFER_BIT;
1580 if (qflags &
flags) {
1581 uint32_t score =
av_popcount(qflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1582 if (score < min_score) {
1590 qf[
index].queueFamilyProperties.timestampValidBits++;
1596 VkQueueFamilyVideoPropertiesKHR *qf_vid, uint32_t num_qf,
1597 VkVideoCodecOperationFlagsKHR
flags)
1600 uint32_t min_score = UINT32_MAX;
1602 for (
int i = 0;
i < num_qf;
i++) {
1603 const VkQueueFlags qflags = qf[
i].queueFamilyProperties.queueFlags;
1604 const VkVideoCodecOperationFlagsKHR vflags = qf_vid[
i].videoCodecOperations;
1606 if (!(qflags & (VK_QUEUE_VIDEO_ENCODE_BIT_KHR | VK_QUEUE_VIDEO_DECODE_BIT_KHR)))
1609 if (vflags &
flags) {
1610 uint32_t score =
av_popcount(vflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1611 if (score < min_score) {
1619 qf[
index].queueFamilyProperties.timestampValidBits++;
1631 VkQueueFamilyProperties2 *qf =
NULL;
1632 VkQueueFamilyVideoPropertiesKHR *qf_vid =
NULL;
1635 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &num,
NULL);
1646 qf_vid =
av_malloc_array(num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
1650 for (uint32_t
i = 0;
i < num;
i++) {
1651 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1652 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1654 qf[
i] = (VkQueueFamilyProperties2) {
1655 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
1661 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &num, qf);
1664 for (
int i = 0;
i < num;
i++) {
1666 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_GRAPHICS_BIT) ?
" graphics" :
"",
1667 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_COMPUTE_BIT) ?
" compute" :
"",
1668 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_TRANSFER_BIT) ?
" transfer" :
"",
1669 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ?
" encode" :
"",
1670 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_DECODE_BIT_KHR) ?
" decode" :
"",
1671 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_SPARSE_BINDING_BIT) ?
" sparse" :
"",
1672 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_OPTICAL_FLOW_BIT_NV) ?
" optical_flow" :
"",
1673 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_PROTECTED_BIT) ?
" protected" :
"",
1674 qf[
i].queueFamilyProperties.queueCount);
1678 qf[
i].queueFamilyProperties.timestampValidBits = 0;
1683#ifdef VK_KHR_internally_synchronized_queues
1685 hwctx->
queue_flags |= VK_DEVICE_QUEUE_CREATE_INTERNALLY_SYNCHRONIZED_BIT_KHR;
1689#define PICK_QF(type, vid_op) \
1695 idx = pick_video_queue_family(qf, qf_vid, num, vid_op); \
1697 idx = pick_queue_family(qf, num, type); \
1702 for (i = 0; i < hwctx->nb_qf; i++) { \
1703 if (hwctx->qf[i].idx == idx) { \
1704 hwctx->qf[i].flags |= type; \
1705 hwctx->qf[i].video_caps |= vid_op; \
1709 if (i == hwctx->nb_qf) { \
1710 hwctx->qf[i].idx = idx; \
1711 hwctx->qf[i].num = qf[idx].queueFamilyProperties.queueCount; \
1712 if (p->limit_queues || \
1713 p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) { \
1714 int max = p->limit_queues; \
1715 if (type == VK_QUEUE_GRAPHICS_BIT) \
1716 hwctx->qf[i].num = FFMIN(hwctx->qf[i].num, \
1719 hwctx->qf[i].num = FFMIN(hwctx->qf[i].num, max); \
1721 hwctx->qf[i].flags = type; \
1722 hwctx->qf[i].video_caps = vid_op; \
1727 PICK_QF(VK_QUEUE_GRAPHICS_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1728 PICK_QF(VK_QUEUE_COMPUTE_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1729 PICK_QF(VK_QUEUE_TRANSFER_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1731 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR);
1732 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR);
1734 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR);
1735 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR);
1737#ifdef VK_KHR_video_decode_vp9
1738 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR);
1741#ifdef VK_KHR_video_encode_av1
1742 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR);
1744 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR);
1752 sizeof(VkDeviceQueueCreateInfo));
1753 if (!cd->pQueueCreateInfos)
1756 for (uint32_t
i = 0;
i < hwctx->
nb_qf;
i++) {
1759 VkDeviceQueueCreateInfo *pc;
1760 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++) {
1761 if (hwctx->
qf[
i].
idx == cd->pQueueCreateInfos[j].queueFamilyIndex) {
1771 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++)
1772 av_free((
void *)cd->pQueueCreateInfos[
i].pQueuePriorities);
1773 av_free((
void *)cd->pQueueCreateInfos);
1777 for (uint32_t j = 0; j < hwctx->
qf[
i].
num; j++)
1780 pc = (VkDeviceQueueCreateInfo *)cd->pQueueCreateInfos;
1781 pc[cd->queueCreateInfoCount++] = (VkDeviceQueueCreateInfo) {
1782 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1784 .queueFamilyIndex = hwctx->
qf[
i].
idx,
1785 .queueCount = hwctx->
qf[
i].
num,
1808 vk->DestroyDebugUtilsMessengerEXT(hwctx->
inst, p->debug_ctx,
1812 vk->DestroyInstance(hwctx->
inst, hwctx->
alloc);
1815 dlclose(p->libvulkan);
1826 for (uint32_t
i = 0;
i < p->nb_tot_qfs;
i++) {
1838 int disable_multiplane,
1849 VkDeviceCreateInfo dev_info = {
1850 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1862 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->mprops);
1866 &dev_info.enabledExtensionCount, debug_mode))) {
1867 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1868 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1869 av_free((
void *)dev_info.pQueueCreateInfos);
1875 vk->GetPhysicalDeviceFeatures2(hwctx->
phys_dev, &supported_feats.
device);
1880 dev_info.pNext = p->feats.device.pNext;
1881 dev_info.pEnabledFeatures = &p->feats.device.features;
1886 p->limit_queues = strtol(opt_d->
value,
NULL, 10);
1893 ret = vk->CreateDevice(hwctx->
phys_dev, &dev_info, hwctx->
alloc,
1896 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1897 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1898 av_free((
void *)dev_info.pQueueCreateInfos);
1900 if (ret != VK_SUCCESS) {
1903 for (
int i = 0;
i < dev_info.enabledExtensionCount;
i++)
1904 av_free((
void *)dev_info.ppEnabledExtensionNames[
i]);
1905 av_free((
void *)dev_info.ppEnabledExtensionNames);
1913 p->use_linear_images = strtol(opt_d->
value,
NULL, 10);
1916 p->disable_multiplane = disable_multiplane;
1917 if (!p->disable_multiplane) {
1920 p->disable_multiplane = strtol(opt_d->
value,
NULL, 10);
1924 p->avoid_host_import = p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY;
1927 p->avoid_host_import = strtol(opt_d->
value,
NULL, 10);
1964 VkQueueFamilyProperties2 *qf;
1965 VkQueueFamilyVideoPropertiesKHR *qf_vid;
1966 VkPhysicalDeviceExternalSemaphoreInfo ext_sem_props_info;
1985 p->props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1986 p->props.pNext = &p->hprops;
1987 p->hprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;
1988 p->hprops.pNext = &p->dprops;
1989 p->dprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
1991 vk->GetPhysicalDeviceProperties2(hwctx->
phys_dev, &p->props);
1993 p->props.properties.deviceName);
1996 p->props.properties.limits.optimalBufferCopyRowPitchAlignment);
1998 p->props.properties.limits.minMemoryMapAlignment);
2000 p->props.properties.limits.nonCoherentAtomSize);
2003 p->hprops.minImportedHostPointerAlignment);
2005 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &qf_num,
NULL);
2011 ext_sem_props_info = (VkPhysicalDeviceExternalSemaphoreInfo) {
2012 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
2016 ext_sem_props_info.handleType =
2018 IsWindows8OrGreater()
2019 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2020 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
2022 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
2024 p->ext_sem_props_opaque.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES;
2025 vk->GetPhysicalDeviceExternalSemaphoreProperties(hwctx->
phys_dev,
2026 &ext_sem_props_info,
2027 &p->ext_sem_props_opaque);
2033 qf_vid =
av_malloc_array(qf_num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
2039 for (uint32_t
i = 0;
i < qf_num;
i++) {
2040 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
2041 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
2043 qf[
i] = (VkQueueFamilyProperties2) {
2044 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
2049 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &qf_num, qf);
2051 p->nb_tot_qfs = qf_num;
2054 p->qf_mutex =
av_calloc(qf_num,
sizeof(*p->qf_mutex));
2060 for (uint32_t
i = 0;
i < qf_num;
i++) {
2061 p->qf_mutex[
i] =
av_calloc(qf[
i].queueFamilyProperties.queueCount,
2062 sizeof(**p->qf_mutex));
2063 if (!p->qf_mutex[
i]) {
2067 for (uint32_t j = 0; j < qf[
i].queueFamilyProperties.queueCount; j++) {
2079 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
2081 hwctx->
qf[
i].
flags & (VK_QUEUE_VIDEO_DECODE_BIT_KHR |
2082 VK_QUEUE_VIDEO_ENCODE_BIT_KHR)) {
2089 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
2093 for (
int j = (
i - 1); j >= 0; j--) {
2100 p->img_qfs[p->nb_img_qfs++] = hwctx->
qf[
i].
idx;
2103#if FF_API_VULKAN_SYNC_QUEUES
2105 if (!hwctx->lock_queue)
2107 if (!hwctx->unlock_queue)
2113 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->mprops);
2115 p->vkctx.device =
ctx;
2116 p->vkctx.hwctx = hwctx;
2119 p->compute_qf =
ff_vk_qf_find(&p->vkctx, VK_QUEUE_COMPUTE_BIT, 0);
2120 p->transfer_qf =
ff_vk_qf_find(&p->vkctx, VK_QUEUE_TRANSFER_BIT, 0);
2123 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->mprops);
2135 if (device && device[0]) {
2137 dev_select.
index = strtol(device, &end, 10);
2138 if (end == device) {
2139 dev_select.
index = 0;
2140 dev_select.
name = device;
2156 switch(src_ctx->
type) {
2160 VADisplay dpy = src_hwctx->
display;
2161#if VA_CHECK_VERSION(1, 15, 0)
2163 VADisplayAttribute attr = {
2164 .type = VADisplayPCIID,
2169#if VA_CHECK_VERSION(1, 15, 0)
2170 vas = vaGetDisplayAttributes(dpy, &attr, 1);
2171 if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED)
2172 dev_select.pci_device = (attr.value & 0xFFFF);
2175 if (!dev_select.pci_device) {
2176 vendor = vaQueryVendorString(dpy);
2182 if (strstr(vendor,
"AMD"))
2183 dev_select.vendor_id = 0x1002;
2192 struct stat drm_node_info;
2193 drmDevice *drm_dev_info;
2196 err = fstat(src_hwctx->
fd, &drm_node_info);
2203 dev_select.drm_major = major(drm_node_info.st_dev);
2204 dev_select.drm_minor = minor(drm_node_info.st_dev);
2205 dev_select.has_drm = 1;
2207 err = drmGetDevice(src_hwctx->
fd, &drm_dev_info);
2214 if (drm_dev_info->bustype == DRM_BUS_PCI)
2215 dev_select.pci_device = drm_dev_info->deviceinfo.pci->device_id;
2217 drmFreeDevice(&drm_dev_info);
2227 CudaFunctions *cu = cu_internal->
cuda_dl;
2229 int ret =
CHECK_CU(cu->cuDeviceGetUuid((CUuuid *)&dev_select.uuid,
2236 dev_select.has_uuid = 1;
2251 const void *hwconfig,
2259 p->use_linear_images ? VK_IMAGE_TILING_LINEAR :
2260 VK_IMAGE_TILING_OPTIMAL,
2272 p->use_linear_images ? VK_IMAGE_TILING_LINEAR :
2273 VK_IMAGE_TILING_OPTIMAL,
2287 constraints->
max_width = p->props.properties.limits.maxImageDimension2D;
2288 constraints->
max_height = p->props.properties.limits.maxImageDimension2D;
2301 VkMemoryPropertyFlagBits req_flags,
const void *alloc_extension,
2302 VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
2309 VkMemoryAllocateInfo alloc_info = {
2310 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2311 .pNext = alloc_extension,
2312 .allocationSize = req->size,
2317 for (
int i = 0;
i < p->mprops.memoryTypeCount;
i++) {
2318 const VkMemoryType *
type = &p->mprops.memoryTypes[
i];
2321 if (!(req->memoryTypeBits & (1 <<
i)))
2325 if ((
type->propertyFlags & req_flags) != req_flags)
2329 if (req->size > p->mprops.memoryHeaps[
type->heapIndex].size)
2343 alloc_info.memoryTypeIndex =
index;
2345 ret = vk->AllocateMemory(dev_hwctx->
act_dev, &alloc_info,
2346 dev_hwctx->
alloc, mem);
2347 if (ret != VK_SUCCESS) {
2353 *mem_flags |= p->mprops.memoryTypes[
index].propertyFlags;
2367 if (internal->cuda_fc_ref) {
2373 CudaFunctions *cu = cu_internal->
cuda_dl;
2376 if (internal->cu_sem[
i])
2377 CHECK_CU(cu->cuDestroyExternalSemaphore(internal->cu_sem[
i]));
2378 if (internal->cu_mma[
i])
2379 CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[
i]));
2380 if (internal->ext_mem[
i])
2381 CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[
i]));
2383 if (internal->ext_sem_handle[
i])
2384 CloseHandle(internal->ext_sem_handle[
i]);
2385 if (internal->ext_mem_handle[
i])
2386 CloseHandle(internal->ext_mem_handle[
i]);
2394 if (internal->drm_sync_sem != VK_NULL_HANDLE)
2395 p->vkctx.vkfn.DestroySemaphore(p->p.act_dev, internal->drm_sync_sem,
2415 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
2417 .pSemaphores =
f->sem,
2418 .pValues =
f->sem_value,
2419 .semaphoreCount = nb_sems,
2427 for (
int i = 0;
i < nb_images;
i++) {
2442 void *alloc_pnext,
size_t alloc_pnext_stride)
2444 int img_cnt = 0, err;
2452 while (
f->img[img_cnt]) {
2454 VkImageMemoryRequirementsInfo2 req_desc = {
2455 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
2456 .image =
f->img[img_cnt],
2458 VkMemoryDedicatedAllocateInfo ded_alloc = {
2459 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
2460 .pNext = (
void *)(((uint8_t *)alloc_pnext) + img_cnt*alloc_pnext_stride),
2462 VkMemoryDedicatedRequirements ded_req = {
2463 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
2465 VkMemoryRequirements2 req = {
2466 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
2470 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req);
2473 "plane %d: driver reports prefersDedicatedAllocation=%i requiresDedicatedAllocation=%i\n",
2474 img_cnt, ded_req.prefersDedicatedAllocation, ded_req.requiresDedicatedAllocation);
2476 if (
f->tiling == VK_IMAGE_TILING_LINEAR)
2477 req.memoryRequirements.size =
FFALIGN(req.memoryRequirements.size,
2478 p->props.properties.limits.minMemoryMapAlignment);
2481 use_ded_mem = ded_req.prefersDedicatedAllocation |
2482 ded_req.requiresDedicatedAllocation;
2486 ded_alloc.image =
f->img[img_cnt];
2490 f->tiling == VK_IMAGE_TILING_LINEAR ?
2491 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
2492 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2493 use_ded_mem ? &ded_alloc : (
void *)ded_alloc.pNext,
2494 &
f->flags, &
f->mem[img_cnt])))
2497 f->size[img_cnt] = req.memoryRequirements.size;
2498 bind_info[img_cnt].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
2499 bind_info[img_cnt].image =
f->img[img_cnt];
2500 bind_info[img_cnt].memory =
f->mem[img_cnt];
2506 ret = vk->BindImageMemory2(hwctx->
act_dev, img_cnt, bind_info);
2507 if (ret != VK_SUCCESS) {
2527 VkAccessFlags2 *new_access)
2531 *new_layout = VK_IMAGE_LAYOUT_GENERAL;
2532 *new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2535 *new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
2536 *new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2539 *new_layout = VK_IMAGE_LAYOUT_GENERAL;
2540 *new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2543 *new_layout = VK_IMAGE_LAYOUT_GENERAL;
2544 *new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2547 *new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR;
2548 *new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2551 *new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR;
2552 *new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2555 *new_layout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR;
2556 *new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2570 VkImageLayout new_layout;
2571 VkAccessFlags2 new_access;
2574 uint32_t dst_qf = p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED : p->img_qfs[0];
2575 VkPipelineStageFlagBits2 src_stage = VK_PIPELINE_STAGE_2_NONE;
2577 dst_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR;
2578 src_stage = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
2585 .data = (uint8_t *)hwfc,
2588 .data[0] = (uint8_t *)
frame,
2589 .hw_frames_ctx = &tmp_ref,
2592 VkCommandBuffer cmd_buf;
2594 cmd_buf = exec->
buf;
2600 VK_PIPELINE_STAGE_2_NONE,
2601 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
2607 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
2608 new_access, new_layout, dst_qf);
2610 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
2611 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
2612 .pImageMemoryBarriers = img_bar,
2613 .imageMemoryBarrierCount = nb_img_bar,
2635 VkImageLayout new_layout;
2636 VkAccessFlags2 new_access;
2640 for (
i = 0;
i < p->vkctx.host_image_props.copyDstLayoutCount;
i++) {
2641 if (p->vkctx.host_image_props.pCopyDstLayouts[
i] == new_layout)
2644 if (
i == p->vkctx.host_image_props.copyDstLayoutCount)
2647 for (
i = 0;
i < nb_images;
i++) {
2648 layout_change[
i] = (VkHostImageLayoutTransitionInfoEXT) {
2649 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT,
2651 .oldLayout =
frame->layout[
i],
2652 .newLayout = new_layout,
2653 .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
2654 .subresourceRange.layerCount = 1,
2655 .subresourceRange.levelCount = 1,
2657 frame->layout[
i] = new_layout;
2660 ret = vk->TransitionImageLayoutEXT(p->vkctx.hwctx->act_dev,
2661 nb_images, layout_change);
2662 if (ret != VK_SUCCESS) {
2676 if (hwfc_vk->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT &&
2688 int frame_w,
int frame_h,
int plane)
2705 VkImageTiling tiling, VkImageUsageFlagBits
usage,
2706 VkImageCreateFlags
flags,
int nb_layers,
2718 VkSemaphoreTypeCreateInfo sem_type_info = {
2719 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2720 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2723 VkSemaphoreCreateInfo sem_spawn = {
2724 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2725 .pNext = &sem_type_info,
2728 VkExportSemaphoreCreateInfo ext_sem_info_opaque = {
2729 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
2731 .handleTypes = IsWindows8OrGreater()
2732 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2733 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
2735 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
2740 if (p->ext_sem_props_opaque.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) {
2754 for (
int i = 0; (hwfc_vk->
format[
i] != VK_FORMAT_UNDEFINED);
i++) {
2755 VkImageCreateInfo create_info = {
2756 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2757 .pNext = create_pnext,
2758 .imageType = VK_IMAGE_TYPE_2D,
2762 .arrayLayers = nb_layers,
2765 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2767 .samples = VK_SAMPLE_COUNT_1_BIT,
2768 .pQueueFamilyIndices = p->img_qfs,
2769 .queueFamilyIndexCount = p->nb_img_qfs,
2770 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2771 VK_SHARING_MODE_EXCLUSIVE,
2774 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
2777 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
2779 if (ret != VK_SUCCESS) {
2787 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
2789 if (ret != VK_SUCCESS) {
2796 f->queue_family[
i] = p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED : p->img_qfs[0];
2797 f->layout[
i] = create_info.initialLayout;
2799 f->sem_value[
i] = 0;
2815 VkExternalMemoryHandleTypeFlags *comp_handle_types,
2816 VkExternalMemoryHandleTypeFlags *iexp,
2817 VkExternalMemoryHandleTypeFlagBits
exp)
2825 const VkImageDrmFormatModifierListCreateInfoEXT *drm_mod_info =
2827 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
2828 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && drm_mod_info;
2831 VkExternalImageFormatProperties eprops = {
2832 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
2834 VkImageFormatProperties2 props = {
2835 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
2838 VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
2839 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
2841 .pQueueFamilyIndices = p->img_qfs,
2842 .queueFamilyIndexCount = p->nb_img_qfs,
2843 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2844 VK_SHARING_MODE_EXCLUSIVE,
2846 VkPhysicalDeviceExternalImageFormatInfo enext = {
2847 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
2849 .pNext = has_mods ? &phy_dev_mod_info :
NULL,
2851 VkPhysicalDeviceImageFormatInfo2 pinfo = {
2852 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
2853 .pNext = !
exp ?
NULL : &enext,
2854 .format = hwctx->
format[0],
2855 .type = VK_IMAGE_TYPE_2D,
2857 .usage = hwctx->
usage,
2858 .flags = (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && has_mods) ?
2862 nb_mods = has_mods ? drm_mod_info->drmFormatModifierCount : 1;
2863 for (
int i = 0;
i < nb_mods;
i++) {
2865 phy_dev_mod_info.drmFormatModifier = drm_mod_info->pDrmFormatModifiers[
i];
2867 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
2871 av_log(hwfc,
AV_LOG_VERBOSE,
"GetPhysicalDeviceImageFormatProperties2: mod[%d]=0x%llx -> %s\n",
2872 i, (
unsigned long long)phy_dev_mod_info.drmFormatModifier,
2873 ret == VK_SUCCESS ?
"OK" :
"FAIL");
2874 if (ret == VK_SUCCESS) {
2876 *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes;
2877 if (
exp == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) {
2880 VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT);
2895 VkExternalMemoryHandleTypeFlags e = 0x0;
2898 VkExternalMemoryImageCreateInfo eiinfo = {
2899 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
2906 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
2907 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
2910 (hwctx->
tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
2912 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
2915 hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
2917 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
2921 eminfo[
i].sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
2923 eminfo[
i].handleTypes = e;
2930 av_log(hwfc,
AV_LOG_ERROR,
"vulkan_pool_alloc failed: create_frame failed: %d\n", err);
2938 if ( (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2939 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR))
2941 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)
2943 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR)
2945 else if (hwctx->
usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)
3007 const VkImageDrmFormatModifierListCreateInfoEXT *mod_list =
3009 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
3010 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
3011 mod_list && mod_list->drmFormatModifierCount;
3012 int nb_mods = has_mods ? mod_list->drmFormatModifierCount : 1;
3015 if (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && !has_mods)
3018 VkPhysicalDeviceImageDrmFormatModifierInfoEXT mod_info = {
3019 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
3020 .pQueueFamilyIndices = p->img_qfs,
3021 .queueFamilyIndexCount = p->nb_img_qfs,
3022 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3023 VK_SHARING_MODE_EXCLUSIVE,
3025 VkPhysicalDeviceImageFormatInfo2 pinfo = {
3026 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3027 .type = VK_IMAGE_TYPE_2D,
3029 .usage = hwctx->
usage,
3036 VkVideoProfileListInfoKHR profile_list;
3037 const VkVideoProfileListInfoKHR *pl =
3039 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
3042 profile_list.pNext =
NULL;
3046 VkImageFormatListCreateInfo format_list;
3047 const VkImageFormatListCreateInfo *fl =
3049 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO);
3052 format_list.pNext =
NULL;
3059 hwctx->
format[
i] != VK_FORMAT_UNDEFINED;
i++) {
3060 pinfo.format = hwctx->
format[
i];
3064 for (
int j = 0; j < nb_mods; j++) {
3065 VkImageFormatProperties2 props = {
3066 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
3070 mod_info.drmFormatModifier = mod_list->pDrmFormatModifiers[j];
3072 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
3074 if (ret != VK_SUCCESS) {
3076 "format %i is not supported: %s\n",
3083 if (!p->vkctx.host_image_props.identicalMemoryTypeRequirements) {
3084 VkImageCreateInfo create_info = {
3085 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3087 .imageType = VK_IMAGE_TYPE_2D,
3088 .format = hwctx->
format[0],
3094 .usage = hwctx->
usage,
3095 .samples = VK_SAMPLE_COUNT_1_BIT,
3096 .pQueueFamilyIndices = p->img_qfs,
3097 .queueFamilyIndexCount = p->nb_img_qfs,
3098 .sharingMode = p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3099 VK_SHARING_MODE_EXCLUSIVE,
3101 VkDeviceImageMemoryRequirements req_info = {
3102 .sType = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS,
3103 .pCreateInfo = &create_info,
3104 .planeAspect = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT ?
3105 VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT : 0,
3107 VkMemoryRequirements2 req = {
3108 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3111 vk->GetDeviceImageMemoryRequirements(dev_hwctx->
act_dev, &req_info, &req);
3112 if (!req.memoryRequirements.memoryTypeBits) {
3114 "no compatible memory type\n");
3130 VkImageUsageFlags supported_usage;
3133 int disable_multiplane = p->disable_multiplane ||
3135 int is_lone_dpb = ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR) ||
3136 ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
3137 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)));
3144 if (p->use_linear_images &&
3145 (hwctx->
tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
3146 hwctx->
tiling = VK_IMAGE_TILING_LINEAR;
3156 if (hwctx->
format[0] != VK_FORMAT_UNDEFINED) {
3161 "for the current sw_format %s!\n",
3173 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
3182 NULL, &supported_usage,
3185 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
3194 int drm_mod_with_video = (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
3196 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR));
3198 if (!is_lone_dpb && !drm_mod_with_video) {
3200 hwctx->
usage |= supported_usage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT |
3201 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3202 VK_IMAGE_USAGE_STORAGE_BIT |
3203 VK_IMAGE_USAGE_SAMPLED_BIT);
3211 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR))
3212 hwctx->
usage |= supported_usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
3215 if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
3218 hwctx->
usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
3224 int sampleable = hwctx->
usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
3225 VK_IMAGE_USAGE_STORAGE_BIT);
3226 hwctx->
img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
3228 hwctx->
img_flags |= VK_IMAGE_CREATE_ALIAS_BIT;
3230 hwctx->
img_flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
3239 if ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
3242 const VkVideoProfileListInfoKHR *pl;
3245 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
3248 for (
i = 0;
i < pl->profileCount;
i++) {
3250 if (pl->pProfiles[
i].videoCodecOperation & 0xFFFF0000)
3253 if (
i == pl->profileCount)
3254 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
3259 if ((hwctx->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT) &&
3261 hwctx->
usage &= ~VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
3292 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
3293 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
3295 err = vk->GetImageDrmFormatModifierPropertiesEXT(dev_hwctx->
act_dev,
f->img[0],
3297 if (err != VK_SUCCESS) {
3303 VkDrmFormatModifierPropertiesListEXT modp;
3304 VkFormatProperties2 fmtp;
3305 VkDrmFormatModifierPropertiesEXT *mod_props =
NULL;
3307 modp = (VkDrmFormatModifierPropertiesListEXT) {
3308 .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
3310 fmtp = (VkFormatProperties2) {
3311 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
3316 vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->
phys_dev, fmt->
fallback[
i], &fmtp);
3318 modp.pDrmFormatModifierProperties =
3319 av_calloc(modp.drmFormatModifierCount,
sizeof(*modp.pDrmFormatModifierProperties));
3320 if (!modp.pDrmFormatModifierProperties) {
3324 vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->
phys_dev, fmt->
fallback[
i], &fmtp);
3326 for (uint32_t j = 0; j < modp.drmFormatModifierCount; ++j) {
3327 VkDrmFormatModifierPropertiesEXT *m = &modp.pDrmFormatModifierProperties[j];
3328 if (m->drmFormatModifier == drm_mod.drmFormatModifier) {
3334 if (mod_props ==
NULL) {
3335 av_log(hwfc,
AV_LOG_ERROR,
"No DRM format modifier properties found for modifier 0x%016"PRIx64
"\n",
3336 drm_mod.drmFormatModifier);
3337 av_free(modp.pDrmFormatModifierProperties);
3343 av_free(modp.pDrmFormatModifierProperties);
3407static const struct {
3408 uint32_t drm_fourcc;
3410} vulkan_drm_format_map[] = {
3411 { DRM_FORMAT_R8, VK_FORMAT_R8_UNORM },
3412 { DRM_FORMAT_R16, VK_FORMAT_R16_UNORM },
3413 { DRM_FORMAT_GR88, VK_FORMAT_R8G8_UNORM },
3414 { DRM_FORMAT_RG88, VK_FORMAT_R8G8_UNORM },
3415 { DRM_FORMAT_GR1616, VK_FORMAT_R16G16_UNORM },
3416 { DRM_FORMAT_RG1616, VK_FORMAT_R16G16_UNORM },
3417 { DRM_FORMAT_ARGB8888, VK_FORMAT_B8G8R8A8_UNORM },
3418 { DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM },
3419 { DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM },
3420 { DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM },
3421 { DRM_FORMAT_ARGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
3422 { DRM_FORMAT_ABGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
3423 { DRM_FORMAT_XRGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
3424 { DRM_FORMAT_XBGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
3427#ifdef DRM_FORMAT_XYUV8888
3428 { DRM_FORMAT_XYUV8888, VK_FORMAT_R8G8B8A8_UNORM },
3429 { DRM_FORMAT_XVYU2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 } ,
3430 { DRM_FORMAT_XVYU12_16161616, VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 } ,
3431 { DRM_FORMAT_XVYU16161616, VK_FORMAT_R16G16B16A16_UNORM } ,
3435static inline VkFormat drm_to_vulkan_fmt(uint32_t drm_fourcc)
3438 if (vulkan_drm_format_map[
i].drm_fourcc == drm_fourcc)
3439 return vulkan_drm_format_map[
i].vk_format;
3440 return VK_FORMAT_UNDEFINED;
3449 int bind_counts = 0;
3458 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3459 if (drm_to_vulkan_fmt(
desc->layers[
i].format) == VK_FORMAT_UNDEFINED) {
3461 desc->layers[
i].format);
3472 f->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
3474 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3478 VkSemaphoreTypeCreateInfo sem_type_info = {
3479 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3480 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
3483 VkSemaphoreCreateInfo sem_spawn = {
3484 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3485 .pNext = &sem_type_info,
3490 VkImageDrmFormatModifierExplicitCreateInfoEXT ext_img_mod_spec = {
3491 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
3492 .drmFormatModifier =
desc->objects[0].format_modifier,
3493 .drmFormatModifierPlaneCount =
planes,
3494 .pPlaneLayouts = (
const VkSubresourceLayout *)&ext_img_layouts,
3496 VkExternalMemoryImageCreateInfo ext_img_spec = {
3497 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
3498 .pNext = &ext_img_mod_spec,
3499 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3501 VkImageCreateInfo create_info = {
3502 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3503 .pNext = &ext_img_spec,
3504 .imageType = VK_IMAGE_TYPE_2D,
3505 .format = drm_to_vulkan_fmt(
desc->layers[
i].format),
3510 .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
3511 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
3513 .samples = VK_SAMPLE_COUNT_1_BIT,
3514 .pQueueFamilyIndices =
p->img_qfs,
3515 .queueFamilyIndexCount =
p->nb_img_qfs,
3516 .sharingMode =
p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3517 VK_SHARING_MODE_EXCLUSIVE,
3528 if (sw_vkfmts && sw_vkfmts[
i] != VK_FORMAT_UNDEFINED)
3529 create_info.format = sw_vkfmts[
i];
3533 VkExternalImageFormatProperties ext_props = {
3534 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
3536 VkImageFormatProperties2 props_ret = {
3537 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
3538 .pNext = &ext_props,
3540 VkPhysicalDeviceImageDrmFormatModifierInfoEXT props_drm_mod = {
3541 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
3542 .drmFormatModifier = ext_img_mod_spec.drmFormatModifier,
3543 .pQueueFamilyIndices = create_info.pQueueFamilyIndices,
3544 .queueFamilyIndexCount = create_info.queueFamilyIndexCount,
3545 .sharingMode = create_info.sharingMode,
3547 VkPhysicalDeviceExternalImageFormatInfo props_ext = {
3548 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
3549 .pNext = &props_drm_mod,
3550 .handleType = ext_img_spec.handleTypes,
3552 VkPhysicalDeviceImageFormatInfo2 fmt_props;
3555 create_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT |
3556 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3558 create_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT |
3559 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3561 fmt_props = (VkPhysicalDeviceImageFormatInfo2) {
3562 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3563 .pNext = &props_ext,
3564 .format = create_info.format,
3565 .type = create_info.imageType,
3566 .tiling = create_info.tiling,
3567 .usage = create_info.usage,
3568 .flags = create_info.flags,
3572 ret = vk->GetPhysicalDeviceImageFormatProperties2(hwctx->phys_dev,
3573 &fmt_props, &props_ret);
3574 if (ret != VK_SUCCESS) {
3582 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
3583 hwfc->sw_format,
src->width,
src->height,
i);
3586 for (
int j = 0; j <
planes; j++) {
3587 ext_img_layouts[j].offset =
desc->layers[
i].planes[j].offset;
3588 ext_img_layouts[j].rowPitch =
desc->layers[
i].planes[j].pitch;
3589 ext_img_layouts[j].size = 0;
3590 ext_img_layouts[j].arrayPitch = 0;
3591 ext_img_layouts[j].depthPitch = 0;
3595 ret = vk->CreateImage(hwctx->act_dev, &create_info,
3596 hwctx->alloc, &
f->img[
i]);
3597 if (ret != VK_SUCCESS) {
3604 ret = vk->CreateSemaphore(hwctx->act_dev, &sem_spawn,
3605 hwctx->alloc, &
f->sem[
i]);
3606 if (ret != VK_SUCCESS) {
3613 f->queue_family[
i] = VK_QUEUE_FAMILY_EXTERNAL;
3614 f->layout[
i] = create_info.initialLayout;
3616 f->sem_value[
i] = 0;
3619 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3621 VkImageMemoryRequirementsInfo2 req_desc = {
3622 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
3625 VkMemoryDedicatedRequirements ded_req = {
3626 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
3628 VkMemoryRequirements2 req2 = {
3629 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3634 VkMemoryFdPropertiesKHR fdmp = {
3635 .sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR,
3641 VkImportMemoryFdInfoKHR idesc = {
3642 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
3643 .fd = dup(
desc->objects[
desc->layers[
i].planes[0].object_index].fd),
3644 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3646 VkMemoryDedicatedAllocateInfo ded_alloc = {
3647 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
3649 .image = req_desc.image,
3653 ret = vk->GetMemoryFdPropertiesKHR(hwctx->act_dev,
3654 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3656 if (ret != VK_SUCCESS) {
3664 vk->GetImageMemoryRequirements2(hwctx->act_dev, &req_desc, &req2);
3667 req2.memoryRequirements.memoryTypeBits = fdmp.memoryTypeBits;
3670 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
3671 (ded_req.prefersDedicatedAllocation ||
3672 ded_req.requiresDedicatedAllocation) ?
3673 &ded_alloc : ded_alloc.pNext,
3674 &
f->flags, &
f->mem[
i]);
3680 f->size[
i] = req2.memoryRequirements.size;
3683 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3685 for (
int j = 0; j <
planes; j++) {
3686 VkImageAspectFlagBits aspect = j == 0 ? VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT :
3687 j == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3688 VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
3690 plane_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO;
3692 plane_info[bind_counts].planeAspect = aspect;
3694 bind_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
3696 bind_info[bind_counts].image =
f->img[
i];
3697 bind_info[bind_counts].memory =
f->mem[
i];
3700 bind_info[bind_counts].memoryOffset = 0;
3707 ret = vk->BindImageMemory2(hwctx->act_dev, bind_counts, bind_info);
3708 if (ret != VK_SUCCESS) {
3736#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
3738 VkCommandBuffer cmd_buf;
3744 for (
int i = 0;
i <
desc->nb_objects;
i++) {
3745 VkSemaphoreTypeCreateInfo sem_type_info = {
3746 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3747 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
3749 VkSemaphoreCreateInfo sem_spawn = {
3750 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3751 .pNext = &sem_type_info,
3753 VkImportSemaphoreFdInfoKHR import_info;
3754 struct dma_buf_export_sync_file implicit_fd_info = {
3755 .flags = DMA_BUF_SYNC_READ,
3759 if (ioctl(
desc->objects[
i].fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE,
3760 &implicit_fd_info)) {
3765 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3769 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3770 hwctx->
alloc, &drm_sync_sem[
i]);
3771 if (ret != VK_SUCCESS) {
3776 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3780 import_info = (VkImportSemaphoreFdInfoKHR) {
3781 .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
3782 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
3783 .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
3784 .semaphore = drm_sync_sem[
i],
3785 .fd = implicit_fd_info.fd,
3788 ret = vk->ImportSemaphoreFdKHR(hwctx->
act_dev, &import_info);
3789 if (ret != VK_SUCCESS) {
3794 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3800 cmd_buf = exec->
buf;
3804 for (
int i = 0;
i <
desc->nb_objects;
i++)
3805 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3811 drm_sync_sem,
desc->nb_objects,
3812 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 1);
3815 VK_PIPELINE_STAGE_2_NONE,
3816 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
3823 VK_PIPELINE_STAGE_2_NONE,
3824 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
3826 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT : 0x0) |
3828 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT : 0x0),
3829 VK_IMAGE_LAYOUT_GENERAL,
3830 p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED :
p->img_qfs[0]);
3832 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
3833 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
3834 .pImageMemoryBarriers = img_bar,
3835 .imageMemoryBarrierCount = nb_img_bar,
3846 "image may be corrupted.\n");
3862 if ((err = vulkan_map_from_drm_frame_desc(hwfc, &
f,
src,
flags)))
3866 dst->data[0] = (uint8_t *)
f;
3868 dst->height =
src->height;
3871 &vulkan_unmap_from_drm,
f);
3875 err = vulkan_map_from_drm_frame_sync(hwfc,
dst,
desc,
flags);
3898 VASurfaceID surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
3904 vaSyncSurface(vaapi_ctx->
display, surface_id);
3912 err = vulkan_map_from_drm(dst_fc,
dst,
tmp,
flags);
3929 VkDeviceMemory mem,
size_t size)
3937 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3938 .type = IsWindows8OrGreater()
3939 ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
3940 : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT,
3943 VkMemoryGetWin32HandleInfoKHR export_info = {
3944 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
3946 .handleType = IsWindows8OrGreater()
3947 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
3948 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
3951 ret = vk->GetMemoryWin32HandleKHR(hwctx->
act_dev, &export_info,
3952 &ext_desc.handle.win32.handle);
3953 if (ret != VK_SUCCESS) {
3958 dst_int->ext_mem_handle[idx] = ext_desc.handle.win32.handle;
3960 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3961 .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
3964 VkMemoryGetFdInfoKHR export_info = {
3965 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
3967 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
3970 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
3971 &ext_desc.handle.fd);
3972 if (ret != VK_SUCCESS) {
3979 ret =
CHECK_CU(cu->cuImportExternalMemory(&dst_int->ext_mem[idx], &ext_desc));
3982 close(ext_desc.handle.fd);
4001 VkSemaphoreGetWin32HandleInfoKHR sem_export = {
4002 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
4004 .handleType = IsWindows8OrGreater()
4005 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
4006 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
4008 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
4012 VkSemaphoreGetFdInfoKHR sem_export = {
4013 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
4015 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
4017 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
4023 ret = vk->GetSemaphoreWin32HandleKHR(hwctx->
act_dev, &sem_export,
4024 &ext_sem_desc.handle.win32.handle);
4026 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &sem_export,
4027 &ext_sem_desc.handle.fd);
4029 if (ret != VK_SUCCESS) {
4035 dst_int->ext_sem_handle[idx] = ext_sem_desc.handle.win32.handle;
4038 ret =
CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[idx],
4042 close(ext_sem_desc.handle.fd);
4070 CudaFunctions *cu = cu_internal->
cuda_dl;
4071 CUarray_format cufmt =
desc->comp[0].depth > 8 ? CU_AD_FORMAT_UNSIGNED_INT16 :
4072 CU_AD_FORMAT_UNSIGNED_INT8;
4073 const int elem_size = 1 + (
desc->comp[0].depth > 8);
4076 dst_int = dst_f->internal;
4078 if (!dst_int->cuda_fc_ref) {
4082 if (!dst_int->cuda_fc_ref)
4086 for (
int i = 0;
i < nb_images;
i++) {
4087 err = export_mem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
4088 dst_f->mem[
i], dst_f->size[
i]);
4092 err = export_sem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
4098 if (nb_images !=
planes) {
4102 if (
desc->comp[
i].step / elem_size > 1) {
4104 "Cannot map a multiplane Vulkan image (%d image(s) "
4105 "for %d plane(s)) to CUDA; create the Vulkan device "
4106 "with the disable_multiplane=1 option (one image per "
4107 "plane) for CUDA interop.\n", nb_images,
planes);
4112 VkImageSubresource subres = {
4113 .aspectMask =
i == 2 ? VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT :
4114 i == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
4115 VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT
4117 VkSubresourceLayout
layout = { 0 };
4118 vk->GetImageSubresourceLayout(hwctx->
act_dev, dst_f->img[
FFMIN(
i, nb_images - 1)],
4125 CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = {
4130 .NumChannels =
desc->comp[
i].step / elem_size,
4138 tex_desc.arrayDesc.Width = p_w;
4139 tex_desc.arrayDesc.Height = p_h;
4141 ret =
CHECK_CU(cu->cuExternalMemoryGetMappedMipmappedArray(&dst_int->cu_mma[
i],
4142 dst_int->ext_mem[
FFMIN(
i, nb_images - 1)],
4149 ret =
CHECK_CU(cu->cuMipmappedArrayGetLevel(&dst_int->cu_array[
i],
4150 dst_int->cu_mma[
i], 0));
4183 CudaFunctions *cu = cu_internal->
cuda_dl;
4194 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
4198 err = vulkan_export_to_cuda(hwfc,
src->hw_frames_ctx,
dst);
4204 dst_int = dst_f->internal;
4206 for (
int i = 0;
i < nb_images;
i++) {
4207 s_w_par[
i].params.fence.value = dst_f->sem_value[
i] + 0;
4208 s_s_par[
i].params.fence.value = dst_f->sem_value[
i] + 1;
4211 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
4212 nb_images, cuda_dev->stream));
4217 CUDA_MEMCPY2D cpy = {
4218 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
4219 .srcDevice = (CUdeviceptr)
src->data[
i],
4220 .srcPitch =
src->linesize[
i],
4223 .dstMemoryType = CU_MEMORYTYPE_ARRAY,
4224 .dstArray = dst_int->cu_array[
i],
4230 cpy.WidthInBytes = p_w *
desc->comp[
i].step;
4233 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
4238 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
4239 nb_images, cuda_dev->stream));
4243 for (
int i = 0;
i < nb_images;
i++)
4244 dst_f->sem_value[
i]++;
4265 switch (
src->format) {
4270 return vulkan_map_from_vaapi(hwfc,
dst,
src,
flags);
4276 return vulkan_map_from_drm(hwfc,
dst,
src,
flags);
4286typedef struct VulkanDRMMapping {
4287 AVDRMFrameDescriptor drm_desc;
4305static inline uint32_t vulkan_fmt_to_drm(
VkFormat vkfmt)
4308 if (vulkan_drm_format_map[
i].vk_format == vkfmt)
4309 return vulkan_drm_format_map[
i].drm_fourcc;
4310 return DRM_FORMAT_INVALID;
4313#define MAX_MEMORY_PLANES 4
4314static VkImageAspectFlags plane_index_to_aspect(
int plane) {
4315 if (plane == 0)
return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
4316 if (plane == 1)
return VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT;
4317 if (plane == 2)
return VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
4318 if (plane == 3)
return VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT;
4321 return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
4324#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
4334 if (
f->internal->drm_sync_sem == VK_NULL_HANDLE) {
4335 VkExportSemaphoreCreateInfo exp_info = {
4336 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
4337 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
4339 VkSemaphoreTypeCreateInfo type_info = {
4340 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
4342 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
4344 VkSemaphoreCreateInfo sem_create = {
4345 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
4346 .pNext = &type_info,
4348 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_create, hwctx->
alloc,
4349 &
f->internal->drm_sync_sem);
4350 if (ret != VK_SUCCESS) {
4362 for (
int i = 0;
i < nb_sems;
i++)
4365 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
4367 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 0);
4369 VkSemaphoreGetFdInfoKHR get_fd_info = {
4370 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
4371 .semaphore =
f->internal->drm_sync_sem,
4372 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
4374 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &get_fd_info, &sync_fd);
4375 if (ret != VK_SUCCESS) {
4377 "Failed to get sync fd from DRM map export semaphore: %s\n",
4400 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
4401 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
4403 const int nb_sems = nb_images;
4404 int free_drm_desc_on_err = 1;
4415#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
4417 f->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
4418 vk->GetSemaphoreFdKHR && vk->CreateSemaphore) {
4419 err = vulkan_drm_export_sync_fd(hwfc,
f, fp, nb_sems);
4428 VkSemaphoreWaitInfo wait_info = {
4429 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
4431 .semaphoreCount = nb_sems,
4432 .pSemaphores =
f->sem,
4433 .pValues =
f->sem_value,
4435 vk->WaitSemaphores(hwctx->
act_dev, &wait_info, UINT64_MAX);
4443 free_drm_desc_on_err = 0;
4445 ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->
act_dev,
f->img[0],
4447 if (ret != VK_SUCCESS) {
4453 for (
int i = 0; (
i <
planes) && (
f->mem[
i]);
i++) {
4454 VkMemoryGetFdInfoKHR export_info = {
4455 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
4456 .memory =
f->mem[
i],
4457 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
4460 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
4462 if (ret != VK_SUCCESS) {
4468#if HAVE_LINUX_DMA_BUF_H && defined(DMA_BUF_IOCTL_IMPORT_SYNC_FILE)
4470 int dup_fd = dup(sync_fd);
4472 struct dma_buf_import_sync_file import_info = {
4473 .flags = DMA_BUF_SYNC_WRITE,
4476 if (ioctl(drm_desc->
objects[
i].
fd, DMA_BUF_IOCTL_IMPORT_SYNC_FILE, &import_info) < 0)
4495 drm_desc->
layers[
i].
format = vulkan_fmt_to_drm(plane_vkfmt);
4505 VkSubresourceLayout
layout;
4506 int aspect_plane = (nb_images == 1) ?
i : j;
4507 VkImageSubresource sub = {
4508 .aspectMask = plane_index_to_aspect(aspect_plane),
4525 if (
f->tiling == VK_IMAGE_TILING_OPTIMAL)
4531 dst->height =
src->height;
4532 dst->data[0] = (uint8_t *)drm_desc;
4545 if (free_drm_desc_on_err)
4585 switch (
dst->format) {
4595 return vulkan_map_to_vaapi(hwfc,
dst,
src,
flags);
4607 AVFrame *swf, VkBufferImageCopy *region,
4616 region[
i].bufferRowLength,
4620 region[
i].imageExtent.height);
4623 if (err != VK_SUCCESS) {
4630 if (err != VK_SUCCESS) {
4640 region[
i].bufferRowLength,
4642 region[
i].imageExtent.height);
4649 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4656 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4657 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4659 size_t buf_offset = 0;
4663 region[
i] = (VkBufferImageCopy) {
4664 .bufferOffset = buf_offset,
4666 p->props.properties.limits.optimalBufferCopyRowPitchAlignment),
4667 .bufferImageHeight = p_h,
4668 .imageSubresource.layerCount = 1,
4669 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4673 buf_offset +=
FFALIGN(p_h*region[
i].bufferRowLength,
4674 p->props.properties.limits.optimalBufferCopyOffsetAlignment);
4679 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
4680 p->vkctx.host_cached_flag);
4688 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4695 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4696 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4705 while (swf->
buf[nb_src_bufs])
4709 if (nb_src_bufs == 1) {
4711 swf->
data[0], VK_WHOLE_SIZE, swf->
buf[0],
4718 region[
i].bufferOffset =
dst[0]->virtual_offset +
4720 }
else if (nb_src_bufs ==
planes) {
4723 swf->
data[
i], VK_WHOLE_SIZE,
4724 swf->
buf[
i], buf_usage);
4729 region[
i].bufferOffset =
dst[
i]->virtual_offset;
4739 for (
int i = 0;
i < (*nb_bufs);
i++)
4760 int nb_layout_ch = 0;
4764 for (
int i = 0;
i < nb_images;
i++) {
4766 for (
int j = 0; j < p->vkctx.host_image_props.copySrcLayoutCount; j++) {
4767 if (hwf_vk->
layout[
i] == p->vkctx.host_image_props.pCopySrcLayouts[j]) {
4777 layout_ch_info[nb_layout_ch] = (VkHostImageLayoutTransitionInfoEXT) {
4778 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT,
4779 .image = hwf_vk->
img[
i],
4780 .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
4781 .newLayout = VK_IMAGE_LAYOUT_GENERAL,
4782 .subresourceRange = {
4783 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4789 hwf_vk->
layout[
i] = layout_ch_info[nb_layout_ch].newLayout;
4794 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
4795 .pSemaphores = hwf_vk->
sem,
4797 .semaphoreCount = nb_images,
4803 vk->TransitionImageLayoutEXT(hwctx->
act_dev,
4804 nb_layout_ch, layout_ch_info);
4807 VkMemoryToImageCopyEXT region_info = {
4808 .sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT,
4809 .imageSubresource = {
4813 VkCopyMemoryToImageInfoEXT copy_info = {
4814 .sType = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT,
4816 .pRegions = ®ion_info,
4819 int img_idx =
FFMIN(
i, (nb_images - 1));
4823 region_info.pHostPointer = swf->
data[
i];
4824 region_info.memoryRowLength = swf->
linesize[
i] /
desc->comp[
i].step;
4826 region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 };
4827 copy_info.dstImage = hwf_vk->
img[img_idx];
4828 copy_info.dstImageLayout = hwf_vk->
layout[img_idx];
4830 vk->CopyMemoryToImageEXT(hwctx->
act_dev, ©_info);
4833 VkImageToMemoryCopyEXT region_info = {
4834 .sType = VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT,
4835 .imageSubresource = {
4839 VkCopyImageToMemoryInfoEXT copy_info = {
4840 .sType = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT,
4842 .pRegions = ®ion_info,
4845 int img_idx =
FFMIN(
i, (nb_images - 1));
4849 region_info.pHostPointer = swf->
data[
i];
4850 region_info.memoryRowLength = swf->
linesize[
i] /
desc->comp[
i].step;
4852 region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 };
4853 copy_info.srcImage = hwf_vk->
img[img_idx];
4854 copy_info.srcImageLayout = hwf_vk->
layout[img_idx];
4856 vk->CopyImageToMemoryEXT(hwctx->
act_dev, ©_info);
4875 int host_mapped = 0;
4890 VkCommandBuffer cmd_buf;
4902 int host_copy = hwctx->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
4905 if (!upload && host_copy) {
4906 for (
int i = 0;
i < nb_images;
i++) {
4908 for (
int j = 0; j < p->vkctx.host_image_props.copySrcLayoutCount; j++) {
4909 if (hwf_vk->
layout[
i] == p->vkctx.host_image_props.pCopySrcLayouts[j]) {
4929 region[
i] = (VkBufferImageCopy) {
4932 .bufferImageHeight = p_h,
4933 .imageSubresource.layerCount = 1,
4934 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4960 cmd_buf = exec->
buf;
4968 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
4969 VK_PIPELINE_STAGE_2_TRANSFER_BIT);
4987 for (
int i = 0;
i < nb_bufs;
i++)
4992 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
4993 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,
4994 upload ? VK_ACCESS_TRANSFER_WRITE_BIT :
4995 VK_ACCESS_TRANSFER_READ_BIT,
4996 upload ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL :
4997 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4998 p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED : p->img_qfs[0]);
5000 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
5001 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
5002 .pImageMemoryBarriers = img_bar,
5003 .imageMemoryBarrierCount = nb_img_bar,
5007 int buf_idx =
FFMIN(
i, (nb_bufs - 1));
5008 int img_idx =
FFMIN(
i, (nb_images - 1));
5011 uint32_t orig_stride = region[
i].bufferRowLength;
5012 region[
i].bufferRowLength /=
desc->comp[
i].step;
5016 vk->CmdCopyBufferToImage(cmd_buf, vkbuf->
buf,
5017 hwf_vk->
img[img_idx],
5018 img_bar[img_idx].newLayout,
5021 vk->CmdCopyImageToBuffer(cmd_buf, hwf_vk->
img[img_idx],
5022 img_bar[img_idx].newLayout,
5026 region[
i].bufferRowLength = orig_stride;
5030 if (err >= 0 && !upload) {
5037 for (
int i = 0;
i < nb_bufs;
i++)
5048 switch (
src->format) {
5058 return vulkan_transfer_data_from_cuda(hwfc,
dst,
src);
5062 if (
src->hw_frames_ctx)
5087 CudaFunctions *cu = cu_internal->
cuda_dl;
5098 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
5102 err = vulkan_export_to_cuda(hwfc,
dst->hw_frames_ctx,
src);
5108 dst_int = dst_f->internal;
5110 for (
int i = 0;
i < nb_images;
i++) {
5111 s_w_par[
i].params.fence.value = dst_f->sem_value[
i] + 0;
5112 s_s_par[
i].params.fence.value = dst_f->sem_value[
i] + 1;
5115 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
5116 nb_images, cuda_dev->stream));
5121 CUDA_MEMCPY2D cpy = {
5122 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
5123 .dstDevice = (CUdeviceptr)
dst->data[
i],
5124 .dstPitch =
dst->linesize[
i],
5127 .srcMemoryType = CU_MEMORYTYPE_ARRAY,
5128 .srcArray = dst_int->cu_array[
i],
5134 cpy.WidthInBytes =
w *
desc->comp[
i].step;
5137 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
5142 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
5143 nb_images, cuda_dev->stream));
5147 for (
int i = 0;
i < nb_images;
i++)
5148 dst_f->sem_value[
i]++;
5169 switch (
dst->format) {
5179 return vulkan_transfer_data_to_cuda(hwfc,
dst,
src);
5183 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 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 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
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)
static AVFormatContext * ctx
static AVDictionary * opts
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_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.