21 #define VK_NO_PROTOTYPES
22 #define VK_ENABLE_BETA_EXTENSIONS
26 #include <versionhelpers.h>
53 #include <va/va_drmcommon.h>
56 #include <sys/sysmacros.h>
60 #include <drm_fourcc.h>
64 #if HAVE_LINUX_DMA_BUF_H
65 #include <sys/ioctl.h>
66 #include <linux/dma-buf.h>
72 #define CHECK_CU(x) FF_CUDA_CHECK_DL(cuda_cu, cu, x)
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;
103 #ifdef VK_KHR_video_maintenance2
104 VkPhysicalDeviceVideoMaintenance2FeaturesKHR video_maintenance_2;
106 #ifdef VK_KHR_video_decode_vp9
107 VkPhysicalDeviceVideoDecodeVP9FeaturesKHR vp9_decode;
109 #ifdef VK_KHR_video_encode_av1
110 VkPhysicalDeviceVideoEncodeAV1FeaturesKHR av1_encode;
117 #ifdef VK_KHR_shader_relaxed_extended_instruction
118 VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR relaxed_extended_instruction;
121 #ifdef VK_KHR_internally_synchronized_queues
122 VkPhysicalDeviceInternallySynchronizedQueuesFeaturesKHR internal_queue_sync;
142 VkPhysicalDeviceExternalMemoryHostPropertiesEXT
hprops;
230 feats->
device = (VkPhysicalDeviceFeatures2) {
231 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
235 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES);
237 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES);
239 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES);
242 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES);
244 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES_KHR);
246 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT);
248 #ifdef VK_EXT_shader_long_vector
250 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_LONG_VECTOR_FEATURES_EXT);
253 #ifdef VK_EXT_shader_replicated_composites
255 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_REPLICATED_COMPOSITES_FEATURES_EXT);
258 #ifdef VK_EXT_zero_initialize_device_memory
260 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_DEVICE_MEMORY_FEATURES_EXT);
263 #ifdef VK_KHR_shader_expect_assume
265 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES_KHR);
269 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR);
270 #ifdef VK_KHR_video_maintenance2
272 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR);
274 #ifdef VK_KHR_video_decode_vp9
276 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR);
278 #ifdef VK_KHR_video_encode_av1
280 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR);
284 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);
286 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR);
288 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT);
290 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR);
292 #ifdef VK_KHR_shader_relaxed_extended_instruction
294 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR);
297 #ifdef VK_KHR_internally_synchronized_queues
299 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INTERNALLY_SYNCHRONIZED_QUEUES_FEATURES_KHR);
306 #define COPY_VAL(VAL) \
308 dst->VAL = src->VAL; \
311 COPY_VAL(device.features.shaderImageGatherExtended);
312 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
313 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
314 COPY_VAL(device.features.fragmentStoresAndAtomics);
315 COPY_VAL(device.features.vertexPipelineStoresAndAtomics);
316 COPY_VAL(device.features.shaderInt64);
317 COPY_VAL(device.features.shaderInt16);
318 COPY_VAL(device.features.shaderFloat64);
319 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
320 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
322 COPY_VAL(vulkan_1_1.samplerYcbcrConversion);
323 COPY_VAL(vulkan_1_1.storagePushConstant16);
324 COPY_VAL(vulkan_1_1.storageBuffer16BitAccess);
325 COPY_VAL(vulkan_1_1.uniformAndStorageBuffer16BitAccess);
327 COPY_VAL(vulkan_1_2.timelineSemaphore);
328 COPY_VAL(vulkan_1_2.scalarBlockLayout);
329 COPY_VAL(vulkan_1_2.bufferDeviceAddress);
330 COPY_VAL(vulkan_1_2.hostQueryReset);
331 COPY_VAL(vulkan_1_2.storagePushConstant8);
333 COPY_VAL(vulkan_1_2.storageBuffer8BitAccess);
334 COPY_VAL(vulkan_1_2.uniformAndStorageBuffer8BitAccess);
336 COPY_VAL(vulkan_1_2.shaderBufferInt64Atomics);
337 COPY_VAL(vulkan_1_2.shaderSharedInt64Atomics);
338 COPY_VAL(vulkan_1_2.vulkanMemoryModel);
339 COPY_VAL(vulkan_1_2.vulkanMemoryModelDeviceScope);
340 COPY_VAL(vulkan_1_2.vulkanMemoryModelAvailabilityVisibilityChains);
341 COPY_VAL(vulkan_1_2.uniformBufferStandardLayout);
342 COPY_VAL(vulkan_1_2.runtimeDescriptorArray);
343 COPY_VAL(vulkan_1_2.shaderSubgroupExtendedTypes);
344 COPY_VAL(vulkan_1_2.shaderUniformBufferArrayNonUniformIndexing);
345 COPY_VAL(vulkan_1_2.shaderSampledImageArrayNonUniformIndexing);
346 COPY_VAL(vulkan_1_2.shaderStorageBufferArrayNonUniformIndexing);
347 COPY_VAL(vulkan_1_2.shaderStorageImageArrayNonUniformIndexing);
349 COPY_VAL(vulkan_1_3.dynamicRendering);
351 COPY_VAL(vulkan_1_3.synchronization2);
352 COPY_VAL(vulkan_1_3.computeFullSubgroups);
353 COPY_VAL(vulkan_1_3.subgroupSizeControl);
354 COPY_VAL(vulkan_1_3.shaderZeroInitializeWorkgroupMemory);
355 COPY_VAL(vulkan_1_3.dynamicRendering);
357 COPY_VAL(timeline_semaphore.timelineSemaphore);
358 COPY_VAL(subgroup_rotate.shaderSubgroupRotate);
359 COPY_VAL(host_image_copy.hostImageCopy);
361 #ifdef VK_EXT_shader_long_vector
365 #ifdef VK_EXT_shader_replicated_composites
366 COPY_VAL(replicated_composites.shaderReplicatedComposites);
369 #ifdef VK_EXT_zero_initialize_device_memory
370 COPY_VAL(zero_initialize.zeroInitializeDeviceMemory);
373 COPY_VAL(video_maintenance_1.videoMaintenance1);
374 #ifdef VK_KHR_video_maintenance2
375 COPY_VAL(video_maintenance_2.videoMaintenance2);
378 #ifdef VK_KHR_video_decode_vp9
379 COPY_VAL(vp9_decode.videoDecodeVP9);
382 #ifdef VK_KHR_video_encode_av1
383 COPY_VAL(av1_encode.videoEncodeAV1);
386 COPY_VAL(shader_object.shaderObject);
388 COPY_VAL(cooperative_matrix.cooperativeMatrix);
390 COPY_VAL(atomic_float.shaderBufferFloat32Atomics);
391 COPY_VAL(atomic_float.shaderBufferFloat32AtomicAdd);
393 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayout);
394 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayoutScalarBlockLayout);
395 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayout8BitAccess);
396 COPY_VAL(explicit_mem_layout.workgroupMemoryExplicitLayout16BitAccess);
398 #ifdef VK_KHR_shader_relaxed_extended_instruction
399 COPY_VAL(relaxed_extended_instruction.shaderRelaxedExtendedInstruction);
402 #ifdef VK_KHR_shader_expect_assume
403 COPY_VAL(expect_assume.shaderExpectAssume);
406 #ifdef VK_KHR_internally_synchronized_queues
407 COPY_VAL(internal_queue_sync.internallySynchronizedQueues);
413 #define ASPECT_2PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT)
414 #define ASPECT_3PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)
426 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_GRAY8, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8_UNORM } },
427 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
428 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY12, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
429 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY14, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
430 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
431 { VK_FORMAT_R32_UINT,
AV_PIX_FMT_GRAY32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_UINT } },
432 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GRAYF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_SFLOAT } },
435 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_BGRA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
436 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGBA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
437 { VK_FORMAT_R8G8B8_UNORM,
AV_PIX_FMT_RGB24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8_UNORM } },
438 { VK_FORMAT_B8G8R8_UNORM,
AV_PIX_FMT_BGR24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8_UNORM } },
439 { VK_FORMAT_R16G16B16_UNORM,
AV_PIX_FMT_RGB48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16_UNORM } },
440 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_RGBA64, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
441 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_BGR0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
442 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGB0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
443 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_X2RGB10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
444 { VK_FORMAT_A2B10G10R10_UNORM_PACK32,
AV_PIX_FMT_X2BGR10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2B10G10R10_UNORM_PACK32 } },
445 { VK_FORMAT_R32G32B32_SFLOAT,
AV_PIX_FMT_RGBF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_SFLOAT } },
446 { VK_FORMAT_R16G16B16A16_SFLOAT,
AV_PIX_FMT_RGBAF16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_SFLOAT } },
447 { VK_FORMAT_R32G32B32A32_SFLOAT,
AV_PIX_FMT_RGBAF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_SFLOAT } },
448 { VK_FORMAT_R32G32B32_UINT,
AV_PIX_FMT_RGB96, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_UINT } },
449 { VK_FORMAT_R32G32B32A32_UINT,
AV_PIX_FMT_RGBA128, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_UINT } },
452 { 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 } },
453 { 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 } },
454 { 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 } },
455 { 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 } },
456 { 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 } },
457 { 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 } },
458 { 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 } },
461 { 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 } },
462 { 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 } },
463 { 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 } },
464 { 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 } },
465 { 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 } },
466 { 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 } },
467 { 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 } },
468 { 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 } },
475 { 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 } },
476 { 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 } },
481 { 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 } },
482 { 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 } },
487 { 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 } },
488 { 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 } },
506 { VK_FORMAT_G8B8G8R8_422_UNORM,
AV_PIX_FMT_YUYV422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
507 { VK_FORMAT_B8G8R8G8_422_UNORM,
AV_PIX_FMT_UYVY422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
508 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
AV_PIX_FMT_Y210, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
509 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
AV_PIX_FMT_Y212, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
510 { VK_FORMAT_G16B16G16R16_422_UNORM,
AV_PIX_FMT_Y216, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
513 { 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 } },
514 { 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 } },
515 { 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 } },
518 { 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 } },
519 { 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 } },
520 { 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 } },
521 { 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 } },
524 { 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 } },
525 { 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 } },
526 { 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 } },
527 { 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 } },
530 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_XV30, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
531 { VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
AV_PIX_FMT_XV36, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
532 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_XV48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
553 VkImageTiling tiling,
556 VkImageAspectFlags *
aspect,
557 VkImageUsageFlags *supported_usage,
558 int disable_multiplane,
int need_storage)
564 const VkFormatFeatureFlagBits2 basic_flags = VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
565 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
566 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
570 VkFormatProperties3 fprops = {
571 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3,
573 VkFormatProperties2 prop = {
574 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
577 VkFormatFeatureFlagBits2 feats_primary, feats_secondary;
578 int basics_primary = 0, basics_secondary = 0;
579 int storage_primary = 0, storage_secondary = 0;
581 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
585 feats_primary = tiling == VK_IMAGE_TILING_LINEAR ?
586 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
587 basics_primary = (feats_primary & basic_flags) == basic_flags;
588 storage_primary = !!(feats_primary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
591 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
594 feats_secondary = tiling == VK_IMAGE_TILING_LINEAR ?
595 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
596 basics_secondary = (feats_secondary & basic_flags) == basic_flags;
597 storage_secondary = !!(feats_secondary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
599 basics_secondary = basics_primary;
600 storage_secondary = storage_primary;
603 if (basics_primary &&
605 (!need_storage || (need_storage && (storage_primary | storage_secondary)))) {
620 ((need_storage && (storage_primary | storage_secondary)) ?
621 VK_IMAGE_USAGE_STORAGE_BIT : 0);
623 }
else if (basics_secondary &&
624 (!need_storage || (need_storage && storage_secondary))) {
645 #if CONFIG_VULKAN_STATIC
646 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance,
655 #if CONFIG_VULKAN_STATIC
658 static const char *lib_names[] = {
661 #elif defined(__APPLE__)
672 p->libvulkan = dlopen(lib_names[
i], RTLD_NOW | RTLD_LOCAL);
682 hwctx->
get_proc_addr = (PFN_vkGetInstanceProcAddr)dlsym(
p->libvulkan,
"vkGetInstanceProcAddr");
711 #ifdef VK_KHR_shader_relaxed_extended_instruction
714 #ifdef VK_EXT_shader_long_vector
717 #ifdef VK_EXT_shader_replicated_composites
720 #ifdef VK_EXT_zero_initialize_device_memory
723 #ifdef VK_KHR_shader_expect_assume
727 #ifdef VK_KHR_video_maintenance2
730 #ifdef VK_KHR_internally_synchronized_queues
753 #ifdef VK_KHR_video_decode_vp9
756 #ifdef VK_KHR_video_encode_av1
792 VkDebugUtilsMessageTypeFlagsEXT messageType,
793 const VkDebugUtilsMessengerCallbackDataEXT *
data,
800 switch (
data->messageIdNumber) {
809 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: l =
AV_LOG_VERBOSE;
break;
810 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: l =
AV_LOG_INFO;
break;
811 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: l =
AV_LOG_WARNING;
break;
812 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: l =
AV_LOG_ERROR;
break;
817 for (
int i = 0;
i <
data->cmdBufLabelCount;
i++)
823 #define ADD_VAL_TO_LIST(list, count, val) \
825 list = av_realloc_array(list, ++count, sizeof(*list)); \
827 err = AVERROR(ENOMEM); \
830 list[count - 1] = av_strdup(val); \
831 if (!list[count - 1]) { \
832 err = AVERROR(ENOMEM); \
837 #define RELEASE_PROPS(props, count) \
839 for (int i = 0; i < count; i++) \
840 av_free((void *)((props)[i])); \
841 av_free((void *)props); \
847 VkDeviceSize max_vram = 0, max_visible_vram = 0;
851 for (
int i = 0;
i <
p->mprops.memoryTypeCount;
i++) {
852 const VkMemoryType
type =
p->mprops.memoryTypes[
i];
853 const VkMemoryHeap heap =
p->mprops.memoryHeaps[
type.heapIndex];
854 if (!(
type.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
856 max_vram =
FFMAX(max_vram, heap.size);
857 if (
type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
858 max_visible_vram =
FFMAX(max_visible_vram, heap.size);
861 return max_vram - max_visible_vram < 1024;
877 const char *
const **
dst, uint32_t *num,
881 const char **extension_names =
NULL;
885 int err = 0, found, extensions_found = 0;
888 int optional_exts_num;
889 uint32_t sup_ext_count;
890 char *user_exts_str =
NULL;
892 VkExtensionProperties *sup_ext;
902 if (!user_exts_str) {
907 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count,
NULL);
908 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
911 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count, sup_ext);
919 if (!user_exts_str) {
924 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
925 &sup_ext_count,
NULL);
926 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
929 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
930 &sup_ext_count, sup_ext);
933 for (
int i = 0;
i < optional_exts_num;
i++) {
934 tstr = optional_exts[
i].
name;
938 if (!strcmp(tstr, VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME) &&
946 (!strcmp(tstr, VK_EXT_SHADER_OBJECT_EXTENSION_NAME))) {
950 for (
int j = 0; j < sup_ext_count; j++) {
951 if (!strcmp(tstr, sup_ext[j].extensionName)) {
960 p->vkctx.extensions |= optional_exts[
i].
flag;
968 tstr = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
970 for (
int j = 0; j < sup_ext_count; j++) {
971 if (!strcmp(tstr, sup_ext[j].extensionName)) {
987 #ifdef VK_KHR_shader_relaxed_extended_instruction
989 tstr = VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME;
991 for (
int j = 0; j < sup_ext_count; j++) {
992 if (!strcmp(tstr, sup_ext[j].extensionName)) {
1006 if (user_exts_str) {
1007 char *save, *token =
av_strtok(user_exts_str,
"+", &save);
1010 for (
int j = 0; j < sup_ext_count; j++) {
1011 if (!strcmp(token, sup_ext[j].extensionName)) {
1027 *
dst = extension_names;
1028 *num = extensions_found;
1042 const char *
const **
dst, uint32_t *num,
1049 static const char layer_standard_validation[] = {
"VK_LAYER_KHRONOS_validation" };
1050 int layer_standard_validation_found = 0;
1052 uint32_t sup_layer_count;
1053 VkLayerProperties *sup_layers;
1056 char *user_layers_str =
NULL;
1059 const char **enabled_layers =
NULL;
1060 uint32_t enabled_layers_count = 0;
1068 vk->EnumerateInstanceLayerProperties(&sup_layer_count,
NULL);
1069 sup_layers =
av_malloc_array(sup_layer_count,
sizeof(VkLayerProperties));
1072 vk->EnumerateInstanceLayerProperties(&sup_layer_count, sup_layers);
1075 for (
int i = 0;
i < sup_layer_count;
i++)
1079 if (!debug_opt && !user_layers)
1084 if (!strcmp(debug_opt->
value,
"printf")) {
1086 }
else if (!strcmp(debug_opt->
value,
"validate")) {
1088 }
else if (!strcmp(debug_opt->
value,
"practices")) {
1091 char *end_ptr =
NULL;
1092 int idx = strtol(debug_opt->
value, &end_ptr, 10);
1093 if (end_ptr == debug_opt->
value || end_ptr[0] !=
'\0' ||
1108 for (
int i = 0;
i < sup_layer_count;
i++) {
1109 if (!strcmp(layer_standard_validation, sup_layers[
i].layerName)) {
1111 layer_standard_validation);
1112 ADD_VAL_TO_LIST(enabled_layers, enabled_layers_count, layer_standard_validation);
1114 layer_standard_validation_found = 1;
1118 if (!layer_standard_validation_found) {
1120 "Validation Layer \"%s\" not supported\n", layer_standard_validation);
1131 if (!user_layers_str) {
1136 token =
av_strtok(user_layers_str,
"+", &save);
1141 if (!strcmp(layer_standard_validation, token) && layer_standard_validation_found) {
1147 for (
int j = 0; j < sup_layer_count; j++) {
1148 if (!strcmp(token, sup_layers[j].layerName)) {
1159 if (!strcmp(layer_standard_validation, token))
1163 "Layer \"%s\" not supported\n", token);
1180 *
dst = enabled_layers;
1181 *num = enabled_layers_count;
1196 VkApplicationInfo application_info = {
1197 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
1198 .pApplicationName =
"ffmpeg",
1202 .pEngineName =
"libavutil",
1203 .apiVersion = VK_API_VERSION_1_3,
1208 VkValidationFeaturesEXT validation_features = {
1209 .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
1211 VkInstanceCreateInfo inst_props = {
1212 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
1213 .pApplicationInfo = &application_info,
1229 &inst_props.enabledLayerCount, debug_mode);
1235 &inst_props.enabledExtensionCount, *debug_mode);
1243 static const VkValidationFeatureEnableEXT feat_list_validate[] = {
1244 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1245 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1246 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
1248 validation_features.pEnabledValidationFeatures = feat_list_validate;
1249 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_validate);
1250 inst_props.pNext = &validation_features;
1252 static const VkValidationFeatureEnableEXT feat_list_debug[] = {
1253 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1254 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1255 VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT,
1257 validation_features.pEnabledValidationFeatures = feat_list_debug;
1258 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_debug);
1259 inst_props.pNext = &validation_features;
1261 static const VkValidationFeatureEnableEXT feat_list_practices[] = {
1262 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1263 VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT,
1265 validation_features.pEnabledValidationFeatures = feat_list_practices;
1266 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_practices);
1267 inst_props.pNext = &validation_features;
1271 for (
int i = 0;
i < inst_props.enabledExtensionCount;
i++) {
1272 if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
1273 inst_props.ppEnabledExtensionNames[
i])) {
1274 inst_props.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
1281 ret = vk->CreateInstance(&inst_props, hwctx->
alloc, &hwctx->
inst);
1284 if (
ret != VK_SUCCESS) {
1301 VkDebugUtilsMessengerCreateInfoEXT dbg = {
1302 .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
1303 .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
1304 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
1305 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
1306 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
1307 .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
1308 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
1309 VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
1314 vk->CreateDebugUtilsMessengerEXT(hwctx->
inst, &dbg,
1315 hwctx->
alloc, &
p->debug_ctx);
1321 RELEASE_PROPS(inst_props.ppEnabledLayerNames, inst_props.enabledLayerCount);
1340 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
return "integrated";
1341 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
return "discrete";
1342 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
return "virtual";
1343 case VK_PHYSICAL_DEVICE_TYPE_CPU:
return "software";
1344 default:
return "unknown";
1351 int err = 0, choice = -1;
1357 VkPhysicalDevice *devices =
NULL;
1358 VkPhysicalDeviceIDProperties *idp =
NULL;
1359 VkPhysicalDeviceProperties2 *prop =
NULL;
1360 VkPhysicalDeviceDriverProperties *driver_prop =
NULL;
1361 VkPhysicalDeviceDrmPropertiesEXT *drm_prop =
NULL;
1363 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num,
NULL);
1364 if (
ret != VK_SUCCESS || !num) {
1373 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num, devices);
1374 if (
ret != VK_SUCCESS) {
1393 driver_prop =
av_calloc(num,
sizeof(*driver_prop));
1400 drm_prop =
av_calloc(num,
sizeof(*drm_prop));
1408 for (
int i = 0;
i < num;
i++) {
1410 drm_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT;
1411 driver_prop[
i].pNext = &drm_prop[
i];
1413 driver_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
1414 idp[
i].pNext = &driver_prop[
i];
1415 idp[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
1416 prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1417 prop[
i].pNext = &idp[
i];
1419 vk->GetPhysicalDeviceProperties2(devices[
i], &prop[
i]);
1421 prop[
i].properties.deviceName,
1423 prop[
i].properties.deviceID);
1427 for (
int i = 0;
i < num;
i++) {
1428 if (!strncmp(idp[
i].deviceUUID, select->
uuid, VK_UUID_SIZE)) {
1437 for (
int i = 0;
i < num;
i++) {
1438 if ((select->
drm_major == drm_prop[
i].primaryMajor &&
1439 select->
drm_minor == drm_prop[
i].primaryMinor) ||
1440 (select->
drm_major == drm_prop[
i].renderMajor &&
1441 select->
drm_minor == drm_prop[
i].renderMinor)) {
1450 }
else if (select->
name) {
1452 for (
int i = 0;
i < num;
i++) {
1453 if (strstr(prop[
i].properties.deviceName, select->
name)) {
1464 for (
int i = 0;
i < num;
i++) {
1465 if (select->
pci_device == prop[
i].properties.deviceID) {
1476 for (
int i = 0;
i < num;
i++) {
1477 if (select->
vendor_id == prop[
i].properties.vendorID) {
1487 if (select->
index < num) {
1488 choice = select->
index;
1500 choice, prop[choice].properties.deviceName,
1502 prop[choice].properties.deviceID);
1504 p->props = prop[choice];
1505 p->props.pNext =
NULL;
1506 p->dprops = driver_prop[choice];
1507 p->dprops.pNext =
NULL;
1521 VkQueueFlagBits
flags)
1524 uint32_t min_score = UINT32_MAX;
1526 for (
int i = 0;
i < num_qf;
i++) {
1527 VkQueueFlagBits qflags = qf[
i].queueFamilyProperties.queueFlags;
1530 if ((
flags & VK_QUEUE_TRANSFER_BIT) &&
1531 (qflags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)))
1532 qflags |= VK_QUEUE_TRANSFER_BIT;
1534 if (qflags &
flags) {
1535 uint32_t score =
av_popcount(qflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1536 if (score < min_score) {
1544 qf[
index].queueFamilyProperties.timestampValidBits++;
1550 VkQueueFamilyVideoPropertiesKHR *qf_vid, uint32_t num_qf,
1551 VkVideoCodecOperationFlagsKHR
flags)
1554 uint32_t min_score = UINT32_MAX;
1556 for (
int i = 0;
i < num_qf;
i++) {
1557 const VkQueueFlags qflags = qf[
i].queueFamilyProperties.queueFlags;
1558 const VkVideoCodecOperationFlagsKHR vflags = qf_vid[
i].videoCodecOperations;
1560 if (!(qflags & (VK_QUEUE_VIDEO_ENCODE_BIT_KHR | VK_QUEUE_VIDEO_DECODE_BIT_KHR)))
1563 if (vflags &
flags) {
1564 uint32_t score =
av_popcount(vflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1565 if (score < min_score) {
1573 qf[
index].queueFamilyProperties.timestampValidBits++;
1585 VkQueueFamilyProperties2 *qf =
NULL;
1586 VkQueueFamilyVideoPropertiesKHR *qf_vid =
NULL;
1589 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &num,
NULL);
1600 qf_vid =
av_malloc_array(num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
1604 for (uint32_t
i = 0;
i < num;
i++) {
1605 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1606 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1608 qf[
i] = (VkQueueFamilyProperties2) {
1609 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
1615 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &num, qf);
1618 for (
int i = 0;
i < num;
i++) {
1620 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_GRAPHICS_BIT) ?
" graphics" :
"",
1621 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_COMPUTE_BIT) ?
" compute" :
"",
1622 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_TRANSFER_BIT) ?
" transfer" :
"",
1623 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ?
" encode" :
"",
1624 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_DECODE_BIT_KHR) ?
" decode" :
"",
1625 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_SPARSE_BINDING_BIT) ?
" sparse" :
"",
1626 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_OPTICAL_FLOW_BIT_NV) ?
" optical_flow" :
"",
1627 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_PROTECTED_BIT) ?
" protected" :
"",
1628 qf[
i].queueFamilyProperties.queueCount);
1632 qf[
i].queueFamilyProperties.timestampValidBits = 0;
1637 #ifdef VK_KHR_internally_synchronized_queues
1639 hwctx->
queue_flags |= VK_DEVICE_QUEUE_CREATE_INTERNALLY_SYNCHRONIZED_BIT_KHR;
1643 #define PICK_QF(type, vid_op) \
1649 idx = pick_video_queue_family(qf, qf_vid, num, vid_op); \
1651 idx = pick_queue_family(qf, num, type); \
1656 for (i = 0; i < hwctx->nb_qf; i++) { \
1657 if (hwctx->qf[i].idx == idx) { \
1658 hwctx->qf[i].flags |= type; \
1659 hwctx->qf[i].video_caps |= vid_op; \
1663 if (i == hwctx->nb_qf) { \
1664 hwctx->qf[i].idx = idx; \
1665 hwctx->qf[i].num = qf[idx].queueFamilyProperties.queueCount; \
1666 if (p->limit_queues || \
1667 p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) { \
1668 int max = p->limit_queues; \
1669 if (type == VK_QUEUE_GRAPHICS_BIT) \
1670 hwctx->qf[i].num = FFMIN(hwctx->qf[i].num, \
1673 hwctx->qf[i].num = FFMIN(hwctx->qf[i].num, max); \
1675 hwctx->qf[i].flags = type; \
1676 hwctx->qf[i].video_caps = vid_op; \
1681 PICK_QF(VK_QUEUE_GRAPHICS_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1682 PICK_QF(VK_QUEUE_COMPUTE_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1683 PICK_QF(VK_QUEUE_TRANSFER_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1685 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR);
1686 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR);
1688 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR);
1689 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR);
1691 #ifdef VK_KHR_video_decode_vp9
1692 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR);
1695 #ifdef VK_KHR_video_encode_av1
1696 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR);
1698 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR);
1706 sizeof(VkDeviceQueueCreateInfo));
1707 if (!cd->pQueueCreateInfos)
1710 for (uint32_t
i = 0;
i < hwctx->
nb_qf;
i++) {
1713 VkDeviceQueueCreateInfo *pc;
1714 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++) {
1715 if (hwctx->
qf[
i].
idx == cd->pQueueCreateInfos[j].queueFamilyIndex) {
1725 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++)
1726 av_free((
void *)cd->pQueueCreateInfos[
i].pQueuePriorities);
1727 av_free((
void *)cd->pQueueCreateInfos);
1731 for (uint32_t j = 0; j < hwctx->
qf[
i].
num; j++)
1734 pc = (VkDeviceQueueCreateInfo *)cd->pQueueCreateInfos;
1735 pc[cd->queueCreateInfoCount++] = (VkDeviceQueueCreateInfo) {
1736 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1738 .queueFamilyIndex = hwctx->
qf[
i].
idx,
1739 .queueCount = hwctx->
qf[
i].
num,
1762 vk->DestroyDebugUtilsMessengerEXT(hwctx->
inst,
p->debug_ctx,
1766 vk->DestroyInstance(hwctx->
inst, hwctx->
alloc);
1769 dlclose(
p->libvulkan);
1780 for (uint32_t
i = 0;
i <
p->nb_tot_qfs;
i++) {
1792 int disable_multiplane,
1803 VkDeviceCreateInfo dev_info = {
1804 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1816 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &
p->mprops);
1820 &dev_info.enabledExtensionCount, debug_mode))) {
1821 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1822 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1823 av_free((
void *)dev_info.pQueueCreateInfos);
1829 vk->GetPhysicalDeviceFeatures2(hwctx->
phys_dev, &supported_feats.
device);
1834 dev_info.pNext =
p->feats.device.pNext;
1835 dev_info.pEnabledFeatures = &
p->feats.device.features;
1840 p->limit_queues = strtol(opt_d->
value,
NULL, 10);
1850 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1851 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1852 av_free((
void *)dev_info.pQueueCreateInfos);
1854 if (
ret != VK_SUCCESS) {
1857 for (
int i = 0;
i < dev_info.enabledExtensionCount;
i++)
1858 av_free((
void *)dev_info.ppEnabledExtensionNames[
i]);
1859 av_free((
void *)dev_info.ppEnabledExtensionNames);
1867 p->use_linear_images = strtol(opt_d->
value,
NULL, 10);
1870 p->disable_multiplane = disable_multiplane;
1871 if (!
p->disable_multiplane) {
1874 p->disable_multiplane = strtol(opt_d->
value,
NULL, 10);
1878 p->avoid_host_import =
p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY;
1881 p->avoid_host_import = strtol(opt_d->
value,
NULL, 10);
1918 VkQueueFamilyProperties2 *qf;
1919 VkQueueFamilyVideoPropertiesKHR *qf_vid;
1920 VkPhysicalDeviceExternalSemaphoreInfo ext_sem_props_info;
1939 p->props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1940 p->props.pNext = &
p->hprops;
1941 p->hprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;
1942 p->hprops.pNext = &
p->dprops;
1943 p->dprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
1945 vk->GetPhysicalDeviceProperties2(hwctx->
phys_dev, &
p->props);
1947 p->props.properties.deviceName);
1950 p->props.properties.limits.optimalBufferCopyRowPitchAlignment);
1952 p->props.properties.limits.minMemoryMapAlignment);
1954 p->props.properties.limits.nonCoherentAtomSize);
1957 p->hprops.minImportedHostPointerAlignment);
1959 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &qf_num,
NULL);
1965 ext_sem_props_info = (VkPhysicalDeviceExternalSemaphoreInfo) {
1966 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
1970 ext_sem_props_info.handleType =
1972 IsWindows8OrGreater()
1973 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
1974 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
1976 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
1978 p->ext_sem_props_opaque.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES;
1979 vk->GetPhysicalDeviceExternalSemaphoreProperties(hwctx->
phys_dev,
1980 &ext_sem_props_info,
1981 &
p->ext_sem_props_opaque);
1987 qf_vid =
av_malloc_array(qf_num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
1993 for (uint32_t
i = 0;
i < qf_num;
i++) {
1994 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1995 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1997 qf[
i] = (VkQueueFamilyProperties2) {
1998 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
2003 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &qf_num, qf);
2005 p->nb_tot_qfs = qf_num;
2008 p->qf_mutex =
av_calloc(qf_num,
sizeof(*
p->qf_mutex));
2014 for (uint32_t
i = 0;
i < qf_num;
i++) {
2015 p->qf_mutex[
i] =
av_calloc(qf[
i].queueFamilyProperties.queueCount,
2016 sizeof(**
p->qf_mutex));
2017 if (!
p->qf_mutex[
i]) {
2021 for (uint32_t j = 0; j < qf[
i].queueFamilyProperties.queueCount; j++) {
2033 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
2035 hwctx->
qf[
i].
flags & (VK_QUEUE_VIDEO_DECODE_BIT_KHR |
2036 VK_QUEUE_VIDEO_ENCODE_BIT_KHR)) {
2043 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
2047 for (
int j = (
i - 1); j >= 0; j--) {
2054 p->img_qfs[
p->nb_img_qfs++] = hwctx->
qf[
i].
idx;
2057 #if FF_API_VULKAN_SYNC_QUEUES
2067 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &
p->mprops);
2069 p->vkctx.device =
ctx;
2070 p->vkctx.hwctx = hwctx;
2077 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &
p->mprops);
2089 if (device && device[0]) {
2091 dev_select.
index = strtol(device, &end, 10);
2092 if (end == device) {
2093 dev_select.
index = 0;
2094 dev_select.
name = device;
2110 switch(src_ctx->
type) {
2114 VADisplay dpy = src_hwctx->
display;
2115 #if VA_CHECK_VERSION(1, 15, 0)
2117 VADisplayAttribute attr = {
2118 .type = VADisplayPCIID,
2123 #if VA_CHECK_VERSION(1, 15, 0)
2124 vas = vaGetDisplayAttributes(dpy, &attr, 1);
2125 if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED)
2126 dev_select.pci_device = (attr.value & 0xFFFF);
2129 if (!dev_select.pci_device) {
2130 vendor = vaQueryVendorString(dpy);
2136 if (strstr(vendor,
"AMD"))
2137 dev_select.vendor_id = 0x1002;
2146 struct stat drm_node_info;
2147 drmDevice *drm_dev_info;
2150 err = fstat(src_hwctx->
fd, &drm_node_info);
2157 dev_select.drm_major = major(drm_node_info.st_dev);
2158 dev_select.drm_minor = minor(drm_node_info.st_dev);
2159 dev_select.has_drm = 1;
2161 err = drmGetDevice(src_hwctx->
fd, &drm_dev_info);
2168 if (drm_dev_info->bustype == DRM_BUS_PCI)
2169 dev_select.pci_device = drm_dev_info->deviceinfo.pci->device_id;
2171 drmFreeDevice(&drm_dev_info);
2181 CudaFunctions *cu = cu_internal->
cuda_dl;
2183 int ret =
CHECK_CU(cu->cuDeviceGetUuid((CUuuid *)&dev_select.uuid,
2190 dev_select.has_uuid = 1;
2205 const void *hwconfig,
2213 p->use_linear_images ? VK_IMAGE_TILING_LINEAR :
2214 VK_IMAGE_TILING_OPTIMAL,
2226 p->use_linear_images ? VK_IMAGE_TILING_LINEAR :
2227 VK_IMAGE_TILING_OPTIMAL,
2237 constraints->
max_width =
p->props.properties.limits.maxImageDimension2D;
2238 constraints->
max_height =
p->props.properties.limits.maxImageDimension2D;
2251 VkMemoryPropertyFlagBits req_flags,
const void *alloc_extension,
2252 VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
2259 VkMemoryAllocateInfo alloc_info = {
2260 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2261 .pNext = alloc_extension,
2262 .allocationSize = req->size,
2267 for (
int i = 0;
i <
p->mprops.memoryTypeCount;
i++) {
2268 const VkMemoryType *
type = &
p->mprops.memoryTypes[
i];
2271 if (!(req->memoryTypeBits & (1 <<
i)))
2275 if ((
type->propertyFlags & req_flags) != req_flags)
2279 if (req->size >
p->mprops.memoryHeaps[
type->heapIndex].size)
2293 alloc_info.memoryTypeIndex =
index;
2295 ret = vk->AllocateMemory(dev_hwctx->
act_dev, &alloc_info,
2296 dev_hwctx->
alloc, mem);
2297 if (
ret != VK_SUCCESS) {
2303 *mem_flags |=
p->mprops.memoryTypes[
index].propertyFlags;
2317 if (internal->cuda_fc_ref) {
2323 CudaFunctions *cu = cu_internal->
cuda_dl;
2326 if (internal->cu_sem[
i])
2327 CHECK_CU(cu->cuDestroyExternalSemaphore(internal->cu_sem[
i]));
2328 if (internal->cu_mma[
i])
2329 CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[
i]));
2330 if (internal->ext_mem[
i])
2331 CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[
i]));
2333 if (internal->ext_sem_handle[
i])
2334 CloseHandle(internal->ext_sem_handle[
i]);
2335 if (internal->ext_mem_handle[
i])
2336 CloseHandle(internal->ext_mem_handle[
i]);
2344 if (internal->drm_sync_sem != VK_NULL_HANDLE)
2345 p->vkctx.vkfn.DestroySemaphore(
p->p.act_dev, internal->drm_sync_sem,
2365 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
2367 .pSemaphores =
f->sem,
2368 .pValues =
f->sem_value,
2369 .semaphoreCount = nb_sems,
2377 for (
int i = 0;
i < nb_images;
i++) {
2392 void *alloc_pnext,
size_t alloc_pnext_stride)
2394 int img_cnt = 0, err;
2402 while (
f->img[img_cnt]) {
2404 VkImageMemoryRequirementsInfo2 req_desc = {
2405 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
2406 .image =
f->img[img_cnt],
2408 VkMemoryDedicatedAllocateInfo ded_alloc = {
2409 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
2410 .pNext = (
void *)(((uint8_t *)alloc_pnext) + img_cnt*alloc_pnext_stride),
2412 VkMemoryDedicatedRequirements ded_req = {
2413 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
2415 VkMemoryRequirements2 req = {
2416 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
2420 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req);
2423 "plane %d: driver reports prefersDedicatedAllocation=%i requiresDedicatedAllocation=%i\n",
2424 img_cnt, ded_req.prefersDedicatedAllocation, ded_req.requiresDedicatedAllocation);
2426 if (
f->tiling == VK_IMAGE_TILING_LINEAR)
2427 req.memoryRequirements.size =
FFALIGN(req.memoryRequirements.size,
2428 p->props.properties.limits.minMemoryMapAlignment);
2431 use_ded_mem = ded_req.prefersDedicatedAllocation |
2432 ded_req.requiresDedicatedAllocation;
2436 ded_alloc.image =
f->img[img_cnt];
2440 f->tiling == VK_IMAGE_TILING_LINEAR ?
2441 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
2442 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2443 use_ded_mem ? &ded_alloc : (
void *)ded_alloc.pNext,
2444 &
f->flags, &
f->mem[img_cnt])))
2447 f->size[img_cnt] = req.memoryRequirements.size;
2448 bind_info[img_cnt].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
2449 bind_info[img_cnt].image =
f->img[img_cnt];
2450 bind_info[img_cnt].memory =
f->mem[img_cnt];
2456 ret = vk->BindImageMemory2(hwctx->
act_dev, img_cnt, bind_info);
2457 if (
ret != VK_SUCCESS) {
2477 VkAccessFlags2 *new_access)
2481 *new_layout = VK_IMAGE_LAYOUT_GENERAL;
2482 *new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2485 *new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
2486 *new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2489 *new_layout = VK_IMAGE_LAYOUT_GENERAL;
2490 *new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2493 *new_layout = VK_IMAGE_LAYOUT_GENERAL;
2494 *new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2497 *new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR;
2498 *new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2501 *new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR;
2502 *new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2505 *new_layout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR;
2506 *new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2520 VkImageLayout new_layout;
2521 VkAccessFlags2 new_access;
2524 uint32_t dst_qf =
p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED :
p->img_qfs[0];
2525 VkPipelineStageFlagBits2 src_stage = VK_PIPELINE_STAGE_2_NONE;
2527 dst_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR;
2528 src_stage = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
2535 .
data = (uint8_t *)hwfc,
2539 .hw_frames_ctx = &tmp_ref,
2542 VkCommandBuffer cmd_buf;
2544 cmd_buf = exec->
buf;
2548 VK_PIPELINE_STAGE_2_NONE,
2549 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
2555 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
2556 new_access, new_layout, dst_qf);
2558 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
2559 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
2560 .pImageMemoryBarriers = img_bar,
2561 .imageMemoryBarrierCount = nb_img_bar,
2583 VkImageLayout new_layout;
2584 VkAccessFlags2 new_access;
2588 for (
i = 0;
i <
p->vkctx.host_image_props.copyDstLayoutCount;
i++) {
2589 if (
p->vkctx.host_image_props.pCopyDstLayouts[
i] == new_layout)
2592 if (
i ==
p->vkctx.host_image_props.copyDstLayoutCount)
2595 for (
i = 0;
i < nb_images;
i++) {
2596 layout_change[
i] = (VkHostImageLayoutTransitionInfoEXT) {
2597 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT,
2599 .oldLayout =
frame->layout[
i],
2600 .newLayout = new_layout,
2601 .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
2602 .subresourceRange.layerCount = 1,
2603 .subresourceRange.levelCount = 1,
2605 frame->layout[
i] = new_layout;
2608 ret = vk->TransitionImageLayoutEXT(
p->vkctx.hwctx->act_dev,
2609 nb_images, layout_change);
2610 if (
ret != VK_SUCCESS) {
2624 if (hwfc_vk->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT &&
2636 int frame_w,
int frame_h,
int plane)
2653 VkImageTiling tiling, VkImageUsageFlagBits
usage,
2654 VkImageCreateFlags
flags,
int nb_layers,
2666 VkSemaphoreTypeCreateInfo sem_type_info = {
2667 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2668 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2671 VkSemaphoreCreateInfo sem_spawn = {
2672 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2673 .pNext = &sem_type_info,
2676 VkExportSemaphoreCreateInfo ext_sem_info_opaque = {
2677 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
2679 .handleTypes = IsWindows8OrGreater()
2680 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2681 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
2683 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
2688 if (
p->ext_sem_props_opaque.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) {
2702 for (
int i = 0; (hwfc_vk->
format[
i] != VK_FORMAT_UNDEFINED);
i++) {
2703 VkImageCreateInfo create_info = {
2704 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2705 .pNext = create_pnext,
2706 .imageType = VK_IMAGE_TYPE_2D,
2710 .arrayLayers = nb_layers,
2713 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2715 .samples = VK_SAMPLE_COUNT_1_BIT,
2716 .pQueueFamilyIndices =
p->img_qfs,
2717 .queueFamilyIndexCount =
p->nb_img_qfs,
2718 .sharingMode =
p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2719 VK_SHARING_MODE_EXCLUSIVE,
2722 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
2725 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
2727 if (
ret != VK_SUCCESS) {
2735 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
2737 if (
ret != VK_SUCCESS) {
2744 f->queue_family[
i] =
p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED :
p->img_qfs[0];
2745 f->layout[
i] = create_info.initialLayout;
2747 f->sem_value[
i] = 0;
2763 VkExternalMemoryHandleTypeFlags *comp_handle_types,
2764 VkExternalMemoryHandleTypeFlags *iexp,
2765 VkExternalMemoryHandleTypeFlagBits
exp)
2773 const VkImageDrmFormatModifierListCreateInfoEXT *drm_mod_info =
2775 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
2776 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && drm_mod_info;
2779 VkExternalImageFormatProperties eprops = {
2780 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
2782 VkImageFormatProperties2 props = {
2783 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
2786 VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
2787 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
2789 .pQueueFamilyIndices =
p->img_qfs,
2790 .queueFamilyIndexCount =
p->nb_img_qfs,
2791 .sharingMode =
p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2792 VK_SHARING_MODE_EXCLUSIVE,
2794 VkPhysicalDeviceExternalImageFormatInfo enext = {
2795 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
2797 .pNext = has_mods ? &phy_dev_mod_info :
NULL,
2799 VkPhysicalDeviceImageFormatInfo2 pinfo = {
2800 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
2801 .pNext = !
exp ?
NULL : &enext,
2803 .type = VK_IMAGE_TYPE_2D,
2805 .usage = hwctx->
usage,
2806 .flags = (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && has_mods) ?
2807 (hwctx->
img_flags) : (VkImageCreateFlags)(VK_IMAGE_CREATE_ALIAS_BIT),
2810 nb_mods = has_mods ? drm_mod_info->drmFormatModifierCount : 1;
2811 for (
int i = 0;
i < nb_mods;
i++) {
2813 phy_dev_mod_info.drmFormatModifier = drm_mod_info->pDrmFormatModifiers[
i];
2815 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
2819 av_log(hwfc,
AV_LOG_VERBOSE,
"GetPhysicalDeviceImageFormatProperties2: mod[%d]=0x%llx -> %s\n",
2820 i, (
unsigned long long)phy_dev_mod_info.drmFormatModifier,
2821 ret == VK_SUCCESS ?
"OK" :
"FAIL");
2822 if (
ret == VK_SUCCESS) {
2824 *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes;
2825 if (
exp == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) {
2828 VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT);
2843 VkExternalMemoryHandleTypeFlags e = 0x0;
2846 VkExternalMemoryImageCreateInfo eiinfo = {
2847 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
2854 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
2855 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
2858 (hwctx->
tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
2860 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
2863 hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
2865 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
2869 eminfo[
i].sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
2871 eminfo[
i].handleTypes = e;
2878 av_log(hwfc,
AV_LOG_ERROR,
"vulkan_pool_alloc failed: create_frame failed: %d\n", err);
2886 if ( (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2887 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR))
2889 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)
2891 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR)
2893 else if (hwctx->
usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)
2949 VkImageUsageFlags supported_usage;
2952 int disable_multiplane =
p->disable_multiplane ||
2954 int is_lone_dpb = ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR) ||
2955 ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2956 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)));
2963 if (
p->use_linear_images &&
2964 (hwctx->
tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
2965 hwctx->
tiling = VK_IMAGE_TILING_LINEAR;
2975 if (hwctx->
format[0] != VK_FORMAT_UNDEFINED) {
2980 "for the current sw_format %s!\n",
2992 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
3001 NULL, &supported_usage,
3004 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
3013 int drm_mod_with_video = (hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
3015 VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR));
3017 if (!is_lone_dpb && !drm_mod_with_video) {
3019 hwctx->
usage |= supported_usage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT |
3020 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3021 VK_IMAGE_USAGE_STORAGE_BIT |
3022 VK_IMAGE_USAGE_SAMPLED_BIT);
3025 !(
p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) &&
3026 !(
p->dprops.driverID == VK_DRIVER_ID_MOLTENVK))
3027 hwctx->
usage |= supported_usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
3030 if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
3033 hwctx->
usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
3039 int sampleable = hwctx->
usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
3040 VK_IMAGE_USAGE_STORAGE_BIT);
3041 hwctx->
img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
3043 hwctx->
img_flags |= VK_IMAGE_CREATE_ALIAS_BIT;
3045 hwctx->
img_flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
3054 if ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
3057 const VkVideoProfileListInfoKHR *pl;
3060 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
3063 for (
i = 0;
i < pl->profileCount;
i++) {
3065 if (pl->pProfiles[
i].videoCodecOperation & 0xFFFF0000)
3068 if (
i == pl->profileCount)
3069 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
3080 p->compute_qf->num, 0, 0, 0,
NULL);
3085 p->transfer_qf->num*2, 0, 0, 0,
NULL);
3090 p->transfer_qf->num, 0, 0, 0,
NULL);
3102 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
3103 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
3105 err = vk->GetImageDrmFormatModifierPropertiesEXT(dev_hwctx->
act_dev,
f->img[0],
3107 if (err != VK_SUCCESS) {
3113 VkDrmFormatModifierPropertiesListEXT modp;
3114 VkFormatProperties2 fmtp;
3115 VkDrmFormatModifierPropertiesEXT *mod_props =
NULL;
3117 modp = (VkDrmFormatModifierPropertiesListEXT) {
3118 .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
3120 fmtp = (VkFormatProperties2) {
3121 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
3126 vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->
phys_dev, fmt->
fallback[
i], &fmtp);
3128 modp.pDrmFormatModifierProperties =
3129 av_calloc(modp.drmFormatModifierCount,
sizeof(*modp.pDrmFormatModifierProperties));
3130 if (!modp.pDrmFormatModifierProperties) {
3134 vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->
phys_dev, fmt->
fallback[
i], &fmtp);
3136 for (uint32_t j = 0; j < modp.drmFormatModifierCount; ++j) {
3137 VkDrmFormatModifierPropertiesEXT *m = &modp.pDrmFormatModifierProperties[j];
3138 if (m->drmFormatModifier == drm_mod.drmFormatModifier) {
3144 if (mod_props ==
NULL) {
3145 av_log(hwfc,
AV_LOG_ERROR,
"No DRM format modifier properties found for modifier 0x%016"PRIx64
"\n",
3146 drm_mod.drmFormatModifier);
3147 av_free(modp.pDrmFormatModifierProperties);
3153 av_free(modp.pDrmFormatModifierProperties);
3217 static const struct {
3218 uint32_t drm_fourcc;
3220 } vulkan_drm_format_map[] = {
3221 { DRM_FORMAT_R8, VK_FORMAT_R8_UNORM },
3222 { DRM_FORMAT_R16, VK_FORMAT_R16_UNORM },
3223 { DRM_FORMAT_GR88, VK_FORMAT_R8G8_UNORM },
3224 { DRM_FORMAT_RG88, VK_FORMAT_R8G8_UNORM },
3225 { DRM_FORMAT_GR1616, VK_FORMAT_R16G16_UNORM },
3226 { DRM_FORMAT_RG1616, VK_FORMAT_R16G16_UNORM },
3227 { DRM_FORMAT_ARGB8888, VK_FORMAT_B8G8R8A8_UNORM },
3228 { DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM },
3229 { DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM },
3230 { DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM },
3231 { DRM_FORMAT_ARGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
3232 { DRM_FORMAT_ABGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
3233 { DRM_FORMAT_XRGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
3234 { DRM_FORMAT_XBGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
3237 #ifdef DRM_FORMAT_XYUV8888
3238 { DRM_FORMAT_XYUV8888, VK_FORMAT_R8G8B8A8_UNORM },
3239 { DRM_FORMAT_XVYU2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 } ,
3240 { DRM_FORMAT_XVYU12_16161616, VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 } ,
3241 { DRM_FORMAT_XVYU16161616, VK_FORMAT_R16G16B16A16_UNORM } ,
3245 static inline VkFormat drm_to_vulkan_fmt(uint32_t drm_fourcc)
3248 if (vulkan_drm_format_map[
i].drm_fourcc == drm_fourcc)
3249 return vulkan_drm_format_map[
i].vk_format;
3250 return VK_FORMAT_UNDEFINED;
3259 int bind_counts = 0;
3269 if (drm_to_vulkan_fmt(
desc->layers[
i].format) == VK_FORMAT_UNDEFINED) {
3271 desc->layers[
i].format);
3282 f->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
3284 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3288 VkSemaphoreTypeCreateInfo sem_type_info = {
3289 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3290 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
3293 VkSemaphoreCreateInfo sem_spawn = {
3294 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3295 .pNext = &sem_type_info,
3300 VkImageDrmFormatModifierExplicitCreateInfoEXT ext_img_mod_spec = {
3301 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
3302 .drmFormatModifier =
desc->objects[0].format_modifier,
3303 .drmFormatModifierPlaneCount =
planes,
3304 .pPlaneLayouts = (
const VkSubresourceLayout *)&ext_img_layouts,
3306 VkExternalMemoryImageCreateInfo ext_img_spec = {
3307 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
3308 .pNext = &ext_img_mod_spec,
3309 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3311 VkImageCreateInfo create_info = {
3312 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3313 .pNext = &ext_img_spec,
3314 .imageType = VK_IMAGE_TYPE_2D,
3315 .format = drm_to_vulkan_fmt(
desc->layers[
i].format),
3320 .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
3321 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
3323 .samples = VK_SAMPLE_COUNT_1_BIT,
3324 .pQueueFamilyIndices =
p->img_qfs,
3325 .queueFamilyIndexCount =
p->nb_img_qfs,
3326 .sharingMode =
p->nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3327 VK_SHARING_MODE_EXCLUSIVE,
3338 if (sw_vkfmts && sw_vkfmts[
i] != VK_FORMAT_UNDEFINED)
3339 create_info.format = sw_vkfmts[
i];
3343 VkExternalImageFormatProperties ext_props = {
3344 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
3346 VkImageFormatProperties2 props_ret = {
3347 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
3348 .pNext = &ext_props,
3350 VkPhysicalDeviceImageDrmFormatModifierInfoEXT props_drm_mod = {
3351 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
3352 .drmFormatModifier = ext_img_mod_spec.drmFormatModifier,
3353 .pQueueFamilyIndices = create_info.pQueueFamilyIndices,
3354 .queueFamilyIndexCount = create_info.queueFamilyIndexCount,
3355 .sharingMode = create_info.sharingMode,
3357 VkPhysicalDeviceExternalImageFormatInfo props_ext = {
3358 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
3359 .pNext = &props_drm_mod,
3360 .handleType = ext_img_spec.handleTypes,
3362 VkPhysicalDeviceImageFormatInfo2 fmt_props;
3365 create_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT |
3366 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3368 create_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT |
3369 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3371 fmt_props = (VkPhysicalDeviceImageFormatInfo2) {
3372 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3373 .pNext = &props_ext,
3374 .format = create_info.format,
3375 .type = create_info.imageType,
3376 .tiling = create_info.tiling,
3377 .usage = create_info.usage,
3378 .flags = create_info.flags,
3382 ret = vk->GetPhysicalDeviceImageFormatProperties2(hwctx->
phys_dev,
3383 &fmt_props, &props_ret);
3384 if (
ret != VK_SUCCESS) {
3392 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
3396 for (
int j = 0; j <
planes; j++) {
3397 ext_img_layouts[j].offset =
desc->layers[
i].planes[j].offset;
3398 ext_img_layouts[j].rowPitch =
desc->layers[
i].planes[j].pitch;
3399 ext_img_layouts[j].size = 0;
3400 ext_img_layouts[j].arrayPitch = 0;
3401 ext_img_layouts[j].depthPitch = 0;
3405 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
3407 if (
ret != VK_SUCCESS) {
3414 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3416 if (
ret != VK_SUCCESS) {
3423 f->queue_family[
i] = VK_QUEUE_FAMILY_EXTERNAL;
3424 f->layout[
i] = create_info.initialLayout;
3426 f->sem_value[
i] = 0;
3429 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3431 VkImageMemoryRequirementsInfo2 req_desc = {
3432 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
3435 VkMemoryDedicatedRequirements ded_req = {
3436 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
3438 VkMemoryRequirements2 req2 = {
3439 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3444 VkMemoryFdPropertiesKHR fdmp = {
3445 .sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR,
3451 VkImportMemoryFdInfoKHR idesc = {
3452 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
3453 .fd = dup(
desc->objects[
desc->layers[
i].planes[0].object_index].fd),
3454 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3456 VkMemoryDedicatedAllocateInfo ded_alloc = {
3457 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
3459 .image = req_desc.image,
3463 ret = vk->GetMemoryFdPropertiesKHR(hwctx->
act_dev,
3464 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3466 if (
ret != VK_SUCCESS) {
3474 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req2);
3477 req2.memoryRequirements.memoryTypeBits = fdmp.memoryTypeBits;
3480 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
3481 (ded_req.prefersDedicatedAllocation ||
3482 ded_req.requiresDedicatedAllocation) ?
3483 &ded_alloc : ded_alloc.pNext,
3484 &
f->flags, &
f->mem[
i]);
3490 f->size[
i] = req2.memoryRequirements.size;
3493 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3495 for (
int j = 0; j <
planes; j++) {
3496 VkImageAspectFlagBits aspect = j == 0 ? VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT :
3497 j == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3498 VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
3500 plane_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO;
3502 plane_info[bind_counts].planeAspect = aspect;
3504 bind_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
3506 bind_info[bind_counts].image =
f->img[
i];
3507 bind_info[bind_counts].memory =
f->mem[
i];
3510 bind_info[bind_counts].memoryOffset = 0;
3517 ret = vk->BindImageMemory2(hwctx->
act_dev, bind_counts, bind_info);
3518 if (
ret != VK_SUCCESS) {
3546 #ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
3548 VkCommandBuffer cmd_buf;
3554 for (
int i = 0;
i <
desc->nb_objects;
i++) {
3555 VkSemaphoreTypeCreateInfo sem_type_info = {
3556 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3557 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
3559 VkSemaphoreCreateInfo sem_spawn = {
3560 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3561 .pNext = &sem_type_info,
3563 VkImportSemaphoreFdInfoKHR import_info;
3564 struct dma_buf_export_sync_file implicit_fd_info = {
3565 .flags = DMA_BUF_SYNC_READ,
3569 if (ioctl(
desc->objects[
i].fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE,
3570 &implicit_fd_info)) {
3575 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3579 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3580 hwctx->
alloc, &drm_sync_sem[
i]);
3581 if (
ret != VK_SUCCESS) {
3586 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3590 import_info = (VkImportSemaphoreFdInfoKHR) {
3591 .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
3592 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
3593 .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
3594 .semaphore = drm_sync_sem[
i],
3595 .fd = implicit_fd_info.fd,
3598 ret = vk->ImportSemaphoreFdKHR(hwctx->
act_dev, &import_info);
3599 if (
ret != VK_SUCCESS) {
3604 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3610 cmd_buf = exec->
buf;
3616 drm_sync_sem,
desc->nb_objects,
3617 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 1);
3622 VK_PIPELINE_STAGE_2_NONE,
3623 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
3628 VK_PIPELINE_STAGE_2_NONE,
3629 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
3631 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT : 0x0) |
3633 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT : 0x0),
3634 VK_IMAGE_LAYOUT_GENERAL,
3635 p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED :
p->img_qfs[0]);
3637 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
3638 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
3639 .pImageMemoryBarriers = img_bar,
3640 .imageMemoryBarrierCount = nb_img_bar,
3651 "image may be corrupted.\n");
3667 if ((err = vulkan_map_from_drm_frame_desc(hwfc, &
f,
src,
flags)))
3671 dst->data[0] = (uint8_t *)
f;
3673 dst->height =
src->height;
3676 &vulkan_unmap_from_drm,
f);
3680 err = vulkan_map_from_drm_frame_sync(hwfc,
dst,
desc,
flags);
3703 VASurfaceID surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
3709 vaSyncSurface(vaapi_ctx->display, surface_id);
3717 err = vulkan_map_from_drm(dst_fc,
dst,
tmp,
flags);
3734 VkDeviceMemory mem,
size_t size)
3742 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3743 .type = IsWindows8OrGreater()
3744 ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
3745 : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT,
3748 VkMemoryGetWin32HandleInfoKHR export_info = {
3749 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
3751 .handleType = IsWindows8OrGreater()
3752 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
3753 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
3756 ret = vk->GetMemoryWin32HandleKHR(hwctx->
act_dev, &export_info,
3757 &ext_desc.handle.win32.handle);
3758 if (
ret != VK_SUCCESS) {
3763 dst_int->ext_mem_handle[idx] = ext_desc.handle.win32.handle;
3765 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3766 .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
3769 VkMemoryGetFdInfoKHR export_info = {
3770 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
3772 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
3775 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
3776 &ext_desc.handle.fd);
3777 if (
ret != VK_SUCCESS) {
3784 ret =
CHECK_CU(cu->cuImportExternalMemory(&dst_int->ext_mem[idx], &ext_desc));
3787 close(ext_desc.handle.fd);
3806 VkSemaphoreGetWin32HandleInfoKHR sem_export = {
3807 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
3809 .handleType = IsWindows8OrGreater()
3810 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
3811 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
3813 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3817 VkSemaphoreGetFdInfoKHR sem_export = {
3818 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
3820 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
3822 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3828 ret = vk->GetSemaphoreWin32HandleKHR(hwctx->
act_dev, &sem_export,
3829 &ext_sem_desc.handle.win32.handle);
3831 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &sem_export,
3832 &ext_sem_desc.handle.fd);
3834 if (
ret != VK_SUCCESS) {
3840 dst_int->ext_sem_handle[idx] = ext_sem_desc.handle.win32.handle;
3843 ret =
CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[idx],
3847 close(ext_sem_desc.handle.fd);
3875 CudaFunctions *cu = cu_internal->
cuda_dl;
3876 CUarray_format cufmt =
desc->comp[0].depth > 8 ? CU_AD_FORMAT_UNSIGNED_INT16 :
3877 CU_AD_FORMAT_UNSIGNED_INT8;
3878 const int elem_size = 1 +
desc->comp[0].depth > 8;
3883 if (!dst_int->cuda_fc_ref) {
3887 if (!dst_int->cuda_fc_ref)
3891 for (
int i = 0;
i < nb_images;
i++) {
3892 err = export_mem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
3897 err = export_sem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
3903 if (nb_images !=
planes) {
3907 if (
desc->comp[
i].step / elem_size > 1) {
3909 "Cannot map a multiplane Vulkan image (%d image(s) "
3910 "for %d plane(s)) to CUDA; create the Vulkan device "
3911 "with the disable_multiplane=1 option (one image per "
3912 "plane) for CUDA interop.\n", nb_images,
planes);
3917 VkImageSubresource subres = {
3918 .aspectMask =
i == 2 ? VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT :
3919 i == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3920 VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT
3922 VkSubresourceLayout
layout = { 0 };
3923 vk->GetImageSubresourceLayout(hwctx->
act_dev, dst_f->
img[
FFMIN(
i, nb_images - 1)],
3930 CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = {
3935 .NumChannels =
desc->comp[
i].step / elem_size,
3943 tex_desc.arrayDesc.Width = p_w;
3944 tex_desc.arrayDesc.Height = p_h;
3946 ret =
CHECK_CU(cu->cuExternalMemoryGetMappedMipmappedArray(&dst_int->cu_mma[
i],
3947 dst_int->ext_mem[
FFMIN(
i, nb_images - 1)],
3954 ret =
CHECK_CU(cu->cuMipmappedArrayGetLevel(&dst_int->cu_array[
i],
3955 dst_int->cu_mma[
i], 0));
3988 CudaFunctions *cu = cu_internal->
cuda_dl;
3999 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
4003 err = vulkan_export_to_cuda(hwfc,
src->hw_frames_ctx,
dst);
4011 for (
int i = 0;
i < nb_images;
i++) {
4012 s_w_par[
i].params.fence.value = dst_f->
sem_value[
i] + 0;
4013 s_s_par[
i].params.fence.value = dst_f->
sem_value[
i] + 1;
4016 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
4017 nb_images, cuda_dev->stream));
4022 CUDA_MEMCPY2D cpy = {
4023 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
4024 .srcDevice = (CUdeviceptr)
src->data[
i],
4025 .srcPitch =
src->linesize[
i],
4028 .dstMemoryType = CU_MEMORYTYPE_ARRAY,
4029 .dstArray = dst_int->cu_array[
i],
4035 cpy.WidthInBytes = p_w *
desc->comp[
i].step;
4038 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
4043 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
4044 nb_images, cuda_dev->stream));
4048 for (
int i = 0;
i < nb_images;
i++)
4070 switch (
src->format) {
4075 return vulkan_map_from_vaapi(hwfc,
dst,
src,
flags);
4081 return vulkan_map_from_drm(hwfc,
dst,
src,
flags);
4091 typedef struct VulkanDRMMapping {
4110 static inline uint32_t vulkan_fmt_to_drm(
VkFormat vkfmt)
4113 if (vulkan_drm_format_map[
i].vk_format == vkfmt)
4114 return vulkan_drm_format_map[
i].drm_fourcc;
4115 return DRM_FORMAT_INVALID;
4118 #define MAX_MEMORY_PLANES 4
4119 static VkImageAspectFlags plane_index_to_aspect(
int plane) {
4120 if (plane == 0)
return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
4121 if (plane == 1)
return VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT;
4122 if (plane == 2)
return VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
4123 if (plane == 3)
return VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT;
4126 return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
4129 #ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
4139 if (
f->internal->drm_sync_sem == VK_NULL_HANDLE) {
4140 VkExportSemaphoreCreateInfo exp_info = {
4141 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
4142 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
4144 VkSemaphoreTypeCreateInfo type_info = {
4145 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
4147 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
4149 VkSemaphoreCreateInfo sem_create = {
4150 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
4151 .pNext = &type_info,
4154 &
f->internal->drm_sync_sem);
4155 if (
ret != VK_SUCCESS) {
4167 for (
int i = 0;
i < nb_sems;
i++)
4170 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
4172 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 0);
4174 VkSemaphoreGetFdInfoKHR get_fd_info = {
4175 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
4176 .semaphore =
f->internal->drm_sync_sem,
4177 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
4179 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &get_fd_info, &sync_fd);
4180 if (
ret != VK_SUCCESS) {
4182 "Failed to get sync fd from DRM map export semaphore: %s\n",
4207 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
4208 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
4210 const int nb_sems = nb_images;
4211 int free_drm_desc_on_err = 1;
4222 #ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
4224 f->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
4225 vk->GetSemaphoreFdKHR && vk->CreateSemaphore) {
4226 err = vulkan_drm_export_sync_fd(hwfc,
f, fp, nb_sems);
4235 VkSemaphoreWaitInfo wait_info = {
4236 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
4238 .semaphoreCount = nb_sems,
4239 .pSemaphores =
f->sem,
4240 .pValues =
f->sem_value,
4242 vk->WaitSemaphores(hwctx->
act_dev, &wait_info, UINT64_MAX);
4250 free_drm_desc_on_err = 0;
4252 ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->
act_dev,
f->img[0],
4254 if (
ret != VK_SUCCESS) {
4260 for (
int i = 0; (
i <
planes) && (
f->mem[
i]);
i++) {
4261 VkMemoryGetFdInfoKHR export_info = {
4262 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
4263 .memory =
f->mem[
i],
4264 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
4267 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
4269 if (
ret != VK_SUCCESS) {
4275 #if HAVE_LINUX_DMA_BUF_H && defined(DMA_BUF_IOCTL_IMPORT_SYNC_FILE)
4277 int dup_fd = dup(sync_fd);
4279 struct dma_buf_import_sync_file import_info = {
4280 .flags = DMA_BUF_SYNC_WRITE,
4283 if (ioctl(drm_desc->
objects[
i].
fd, DMA_BUF_IOCTL_IMPORT_SYNC_FILE, &import_info) < 0)
4302 drm_desc->
layers[
i].
format = vulkan_fmt_to_drm(plane_vkfmt);
4312 VkSubresourceLayout
layout;
4313 int aspect_plane = (nb_images == 1) ?
i : j;
4314 VkImageSubresource sub = {
4315 .aspectMask = plane_index_to_aspect(aspect_plane),
4332 if (
f->tiling == VK_IMAGE_TILING_OPTIMAL)
4338 dst->height =
src->height;
4339 dst->data[0] = (uint8_t *)drm_desc;
4352 if (free_drm_desc_on_err)
4392 switch (
dst->format) {
4402 return vulkan_map_to_vaapi(hwfc,
dst,
src,
flags);
4414 AVFrame *swf, VkBufferImageCopy *region,
4424 region[
i].bufferRowLength,
4428 region[
i].imageExtent.height);
4431 if (err != VK_SUCCESS) {
4438 if (err != VK_SUCCESS) {
4448 region[
i].bufferRowLength,
4450 region[
i].imageExtent.height);
4457 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4464 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4465 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4467 size_t buf_offset = 0;
4471 region[
i] = (VkBufferImageCopy) {
4472 .bufferOffset = buf_offset,
4474 p->props.properties.limits.optimalBufferCopyRowPitchAlignment),
4475 .bufferImageHeight = p_h,
4476 .imageSubresource.layerCount = 1,
4477 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4481 buf_offset +=
FFALIGN(p_h*region[
i].bufferRowLength,
4482 p->props.properties.limits.optimalBufferCopyOffsetAlignment);
4487 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
4488 p->vkctx.host_cached_flag);
4496 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4503 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4504 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4513 while (swf->
buf[nb_src_bufs])
4517 if (nb_src_bufs == 1) {
4528 }
else if (nb_src_bufs ==
planes) {
4547 for (
int i = 0;
i < (*nb_bufs);
i++)
4568 int nb_layout_ch = 0;
4572 for (
int i = 0;
i < nb_images;
i++) {
4574 for (
int j = 0; j <
p->vkctx.host_image_props.copySrcLayoutCount; j++) {
4575 if (hwf_vk->
layout[
i] ==
p->vkctx.host_image_props.pCopySrcLayouts[j]) {
4583 layout_ch_info[nb_layout_ch] = (VkHostImageLayoutTransitionInfoEXT) {
4584 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT,
4585 .image = hwf_vk->
img[
i],
4586 .oldLayout = hwf_vk->
layout[
i],
4587 .newLayout = VK_IMAGE_LAYOUT_GENERAL,
4588 .subresourceRange = {
4589 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4595 hwf_vk->
layout[
i] = layout_ch_info[nb_layout_ch].newLayout;
4600 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
4601 .pSemaphores = hwf_vk->
sem,
4603 .semaphoreCount = nb_images,
4609 vk->TransitionImageLayoutEXT(hwctx->
act_dev,
4610 nb_layout_ch, layout_ch_info);
4613 VkMemoryToImageCopyEXT region_info = {
4614 .sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT,
4615 .imageSubresource = {
4619 VkCopyMemoryToImageInfoEXT copy_info = {
4620 .sType = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT,
4622 .pRegions = ®ion_info,
4625 int img_idx =
FFMIN(
i, (nb_images - 1));
4629 region_info.pHostPointer = swf->
data[
i];
4630 region_info.memoryRowLength = swf->
linesize[
i] /
desc->comp[
i].step;
4632 region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 };
4633 copy_info.dstImage = hwf_vk->
img[img_idx];
4634 copy_info.dstImageLayout = hwf_vk->
layout[img_idx];
4636 vk->CopyMemoryToImageEXT(hwctx->
act_dev, ©_info);
4639 VkImageToMemoryCopyEXT region_info = {
4640 .sType = VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT,
4641 .imageSubresource = {
4645 VkCopyImageToMemoryInfoEXT copy_info = {
4646 .sType = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT,
4648 .pRegions = ®ion_info,
4651 int img_idx =
FFMIN(
i, (nb_images - 1));
4655 region_info.pHostPointer = swf->
data[
i];
4656 region_info.memoryRowLength = swf->
linesize[
i] /
desc->comp[
i].step;
4658 region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 };
4659 copy_info.srcImage = hwf_vk->
img[img_idx];
4660 copy_info.srcImageLayout = hwf_vk->
layout[img_idx];
4662 vk->CopyImageToMemoryEXT(hwctx->
act_dev, ©_info);
4681 int host_mapped = 0;
4696 VkCommandBuffer cmd_buf;
4708 if (hwctx->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT &&
4709 !(
p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY))
4717 region[
i] = (VkBufferImageCopy) {
4720 .bufferImageHeight = p_h,
4721 .imageSubresource.layerCount = 1,
4722 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4748 cmd_buf = exec->
buf;
4754 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
4755 VK_PIPELINE_STAGE_2_TRANSFER_BIT);
4779 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
4780 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,
4781 upload ? VK_ACCESS_TRANSFER_WRITE_BIT :
4782 VK_ACCESS_TRANSFER_READ_BIT,
4783 upload ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL :
4784 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4785 p->nb_img_qfs > 1 ? VK_QUEUE_FAMILY_IGNORED :
p->img_qfs[0]);
4787 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
4788 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
4789 .pImageMemoryBarriers = img_bar,
4790 .imageMemoryBarrierCount = nb_img_bar,
4794 int buf_idx =
FFMIN(
i, (nb_bufs - 1));
4795 int img_idx =
FFMIN(
i, (nb_images - 1));
4798 uint32_t orig_stride = region[
i].bufferRowLength;
4799 region[
i].bufferRowLength /=
desc->comp[
i].step;
4803 vk->CmdCopyBufferToImage(cmd_buf, vkbuf->
buf,
4804 hwf_vk->
img[img_idx],
4805 img_bar[img_idx].newLayout,
4808 vk->CmdCopyImageToBuffer(cmd_buf, hwf_vk->
img[img_idx],
4809 img_bar[img_idx].newLayout,
4813 region[
i].bufferRowLength = orig_stride;
4819 }
else if (!upload) {
4826 for (
int i = 0;
i < nb_bufs;
i++)
4837 switch (
src->format) {
4847 return vulkan_transfer_data_from_cuda(hwfc,
dst,
src);
4851 if (
src->hw_frames_ctx)
4876 CudaFunctions *cu = cu_internal->
cuda_dl;
4887 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
4891 err = vulkan_export_to_cuda(hwfc,
dst->hw_frames_ctx,
src);
4899 for (
int i = 0;
i < nb_images;
i++) {
4900 s_w_par[
i].params.fence.value = dst_f->
sem_value[
i] + 0;
4901 s_s_par[
i].params.fence.value = dst_f->
sem_value[
i] + 1;
4904 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
4905 nb_images, cuda_dev->stream));
4910 CUDA_MEMCPY2D cpy = {
4911 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
4912 .dstDevice = (CUdeviceptr)
dst->data[
i],
4913 .dstPitch =
dst->linesize[
i],
4916 .srcMemoryType = CU_MEMORYTYPE_ARRAY,
4917 .srcArray = dst_int->cu_array[
i],
4923 cpy.WidthInBytes =
w *
desc->comp[
i].step;
4926 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
4931 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
4932 nb_images, cuda_dev->stream));
4936 for (
int i = 0;
i < nb_images;
i++)
4958 switch (
dst->format) {
4968 return vulkan_transfer_data_to_cuda(hwfc,
dst,
src);
4972 if (
dst->hw_frames_ctx)