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)
85 #ifdef VK_KHR_shader_expect_assume
86 VkPhysicalDeviceShaderExpectAssumeFeaturesKHR expect_assume;
90 #ifdef VK_KHR_video_maintenance2
91 VkPhysicalDeviceVideoMaintenance2FeaturesKHR video_maintenance_2;
93 #ifdef VK_KHR_video_decode_vp9
94 VkPhysicalDeviceVideoDecodeVP9FeaturesKHR vp9_decode;
96 #ifdef VK_KHR_video_encode_av1
97 VkPhysicalDeviceVideoEncodeAV1FeaturesKHR av1_encode;
105 #ifdef VK_KHR_shader_relaxed_extended_instruction
106 VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR relaxed_extended_instruction;
126 VkPhysicalDeviceExternalMemoryHostPropertiesEXT
hprops;
210 feats->
device = (VkPhysicalDeviceFeatures2) {
211 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
215 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES);
217 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES);
219 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES);
222 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES);
224 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES_KHR);
226 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT);
228 #ifdef VK_KHR_shader_expect_assume
230 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES_KHR);
234 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR);
235 #ifdef VK_KHR_video_maintenance2
237 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR);
239 #ifdef VK_KHR_video_decode_vp9
241 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR);
243 #ifdef VK_KHR_video_encode_av1
245 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR);
249 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);
251 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR);
253 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT);
255 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT);
257 #ifdef VK_KHR_shader_relaxed_extended_instruction
259 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR);
266 #define COPY_VAL(VAL) \
268 dst->VAL = src->VAL; \
271 COPY_VAL(device.features.shaderImageGatherExtended);
272 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
273 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
274 COPY_VAL(device.features.fragmentStoresAndAtomics);
275 COPY_VAL(device.features.vertexPipelineStoresAndAtomics);
276 COPY_VAL(device.features.shaderInt64);
277 COPY_VAL(device.features.shaderInt16);
278 COPY_VAL(device.features.shaderFloat64);
279 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
280 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
282 COPY_VAL(vulkan_1_1.samplerYcbcrConversion);
283 COPY_VAL(vulkan_1_1.storagePushConstant16);
284 COPY_VAL(vulkan_1_1.storageBuffer16BitAccess);
285 COPY_VAL(vulkan_1_1.uniformAndStorageBuffer16BitAccess);
287 COPY_VAL(vulkan_1_2.timelineSemaphore);
288 COPY_VAL(vulkan_1_2.scalarBlockLayout);
289 COPY_VAL(vulkan_1_2.bufferDeviceAddress);
290 COPY_VAL(vulkan_1_2.hostQueryReset);
291 COPY_VAL(vulkan_1_2.storagePushConstant8);
293 COPY_VAL(vulkan_1_2.storageBuffer8BitAccess);
294 COPY_VAL(vulkan_1_2.uniformAndStorageBuffer8BitAccess);
296 COPY_VAL(vulkan_1_2.shaderBufferInt64Atomics);
297 COPY_VAL(vulkan_1_2.shaderSharedInt64Atomics);
298 COPY_VAL(vulkan_1_2.vulkanMemoryModel);
299 COPY_VAL(vulkan_1_2.vulkanMemoryModelDeviceScope);
300 COPY_VAL(vulkan_1_2.uniformBufferStandardLayout);
302 COPY_VAL(vulkan_1_3.dynamicRendering);
304 COPY_VAL(vulkan_1_3.synchronization2);
305 COPY_VAL(vulkan_1_3.computeFullSubgroups);
306 COPY_VAL(vulkan_1_3.subgroupSizeControl);
307 COPY_VAL(vulkan_1_3.shaderZeroInitializeWorkgroupMemory);
308 COPY_VAL(vulkan_1_3.dynamicRendering);
310 COPY_VAL(timeline_semaphore.timelineSemaphore);
311 COPY_VAL(subgroup_rotate.shaderSubgroupRotate);
312 COPY_VAL(host_image_copy.hostImageCopy);
314 COPY_VAL(video_maintenance_1.videoMaintenance1);
315 #ifdef VK_KHR_video_maintenance2
316 COPY_VAL(video_maintenance_2.videoMaintenance2);
319 #ifdef VK_KHR_video_decode_vp9
320 COPY_VAL(vp9_decode.videoDecodeVP9);
323 #ifdef VK_KHR_video_encode_av1
324 COPY_VAL(av1_encode.videoEncodeAV1);
327 COPY_VAL(shader_object.shaderObject);
329 COPY_VAL(cooperative_matrix.cooperativeMatrix);
331 COPY_VAL(descriptor_buffer.descriptorBuffer);
332 COPY_VAL(descriptor_buffer.descriptorBufferPushDescriptors);
334 COPY_VAL(atomic_float.shaderBufferFloat32Atomics);
335 COPY_VAL(atomic_float.shaderBufferFloat32AtomicAdd);
337 #ifdef VK_KHR_shader_relaxed_extended_instruction
338 COPY_VAL(relaxed_extended_instruction.shaderRelaxedExtendedInstruction);
341 #ifdef VK_KHR_shader_expect_assume
342 COPY_VAL(expect_assume.shaderExpectAssume);
348 #define ASPECT_2PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT)
349 #define ASPECT_3PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)
361 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_GRAY8, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8_UNORM } },
362 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
363 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY12, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
364 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY14, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
365 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
366 { VK_FORMAT_R32_UINT,
AV_PIX_FMT_GRAY32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_UINT } },
367 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GRAYF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_SFLOAT } },
370 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_BGRA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
371 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGBA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
372 { VK_FORMAT_R8G8B8_UNORM,
AV_PIX_FMT_RGB24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8_UNORM } },
373 { VK_FORMAT_B8G8R8_UNORM,
AV_PIX_FMT_BGR24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8_UNORM } },
374 { VK_FORMAT_R16G16B16_UNORM,
AV_PIX_FMT_RGB48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16_UNORM } },
375 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_RGBA64, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
376 { VK_FORMAT_R5G6B5_UNORM_PACK16,
AV_PIX_FMT_RGB565, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R5G6B5_UNORM_PACK16 } },
377 { VK_FORMAT_B5G6R5_UNORM_PACK16,
AV_PIX_FMT_BGR565, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B5G6R5_UNORM_PACK16 } },
378 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_BGR0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
379 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGB0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
380 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_X2RGB10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
381 { VK_FORMAT_A2B10G10R10_UNORM_PACK32,
AV_PIX_FMT_X2BGR10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2B10G10R10_UNORM_PACK32 } },
382 { VK_FORMAT_R32G32B32_SFLOAT,
AV_PIX_FMT_RGBF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_SFLOAT } },
383 { VK_FORMAT_R32G32B32A32_SFLOAT,
AV_PIX_FMT_RGBAF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_SFLOAT } },
384 { VK_FORMAT_R32G32B32_UINT,
AV_PIX_FMT_RGB96, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_UINT } },
385 { VK_FORMAT_R32G32B32A32_UINT,
AV_PIX_FMT_RGBA128, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_UINT } },
388 { 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 } },
389 { 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 } },
390 { 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 } },
391 { 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 } },
392 { 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 } },
393 { 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 } },
396 { 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 } },
397 { 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 } },
398 { 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 } },
399 { 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 } },
400 { 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 } },
401 { 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 } },
402 { 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 } },
409 { 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 } },
410 { 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 } },
415 { 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 } },
416 { 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 } },
421 { 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 } },
422 { 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 } },
440 { VK_FORMAT_G8B8G8R8_422_UNORM,
AV_PIX_FMT_YUYV422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
441 { VK_FORMAT_B8G8R8G8_422_UNORM,
AV_PIX_FMT_UYVY422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
442 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
AV_PIX_FMT_Y210, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
443 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
AV_PIX_FMT_Y212, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
444 { VK_FORMAT_G16B16G16R16_422_UNORM,
AV_PIX_FMT_Y216, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
447 { 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 } },
448 { 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 } },
449 { 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 } },
452 { 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 } },
453 { 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 } },
454 { 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 } },
455 { 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 } },
458 { 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 } },
459 { 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 } },
460 { 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 } },
461 { 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 } },
464 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_UYVA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
465 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_XV30, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
466 { VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
AV_PIX_FMT_XV36, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
467 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_XV48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
488 VkImageTiling tiling,
491 VkImageAspectFlags *
aspect,
492 VkImageUsageFlags *supported_usage,
493 int disable_multiplane,
int need_storage)
499 const VkFormatFeatureFlagBits2 basic_flags = VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
500 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
501 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
505 VkFormatProperties3 fprops = {
506 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3,
508 VkFormatProperties2 prop = {
509 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
512 VkFormatFeatureFlagBits2 feats_primary, feats_secondary;
513 int basics_primary = 0, basics_secondary = 0;
514 int storage_primary = 0, storage_secondary = 0;
516 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
520 feats_primary = tiling == VK_IMAGE_TILING_LINEAR ?
521 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
522 basics_primary = (feats_primary & basic_flags) == basic_flags;
523 storage_primary = !!(feats_primary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
526 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
529 feats_secondary = tiling == VK_IMAGE_TILING_LINEAR ?
530 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
531 basics_secondary = (feats_secondary & basic_flags) == basic_flags;
532 storage_secondary = !!(feats_secondary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
534 basics_secondary = basics_primary;
535 storage_secondary = storage_primary;
538 if (basics_primary &&
540 (!need_storage || (need_storage && (storage_primary | storage_secondary)))) {
555 ((need_storage && (storage_primary | storage_secondary)) ?
556 VK_IMAGE_USAGE_STORAGE_BIT : 0);
558 }
else if (basics_secondary &&
559 (!need_storage || (need_storage && storage_secondary))) {
580 #if CONFIG_VULKAN_STATIC
581 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance,
590 #if CONFIG_VULKAN_STATIC
593 static const char *lib_names[] = {
596 #elif defined(__APPLE__)
607 p->
libvulkan = dlopen(lib_names[
i], RTLD_NOW | RTLD_LOCAL);
645 #ifdef VK_KHR_shader_expect_assume
649 #ifdef VK_KHR_video_maintenance2
672 #ifdef VK_KHR_video_decode_vp9
675 #ifdef VK_KHR_video_encode_av1
681 static VkBool32 VKAPI_CALL
vk_dbg_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
682 VkDebugUtilsMessageTypeFlagsEXT messageType,
683 const VkDebugUtilsMessengerCallbackDataEXT *
data,
690 switch (
data->messageIdNumber) {
701 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: l =
AV_LOG_VERBOSE;
break;
702 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: l =
AV_LOG_INFO;
break;
703 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: l =
AV_LOG_WARNING;
break;
704 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: l =
AV_LOG_ERROR;
break;
709 for (
int i = 0;
i <
data->cmdBufLabelCount;
i++)
715 #define ADD_VAL_TO_LIST(list, count, val) \
717 list = av_realloc_array(list, sizeof(*list), ++count); \
719 err = AVERROR(ENOMEM); \
722 list[count - 1] = av_strdup(val); \
723 if (!list[count - 1]) { \
724 err = AVERROR(ENOMEM); \
729 #define RELEASE_PROPS(props, count) \
731 for (int i = 0; i < count; i++) \
732 av_free((void *)((props)[i])); \
733 av_free((void *)props); \
751 const char *
const **
dst, uint32_t *num,
755 const char **extension_names =
NULL;
759 int err = 0, found, extensions_found = 0;
762 int optional_exts_num;
763 uint32_t sup_ext_count;
764 char *user_exts_str =
NULL;
766 VkExtensionProperties *sup_ext;
776 if (!user_exts_str) {
781 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count,
NULL);
782 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
785 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count, sup_ext);
793 if (!user_exts_str) {
798 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
799 &sup_ext_count,
NULL);
800 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
803 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
804 &sup_ext_count, sup_ext);
807 for (
int i = 0;
i < optional_exts_num;
i++) {
808 tstr = optional_exts[
i].
name;
812 if (p->
dprops.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA &&
813 !strcmp(tstr, VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME))
820 !strcmp(tstr, VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME)) {
824 for (
int j = 0; j < sup_ext_count; j++) {
825 if (!strcmp(tstr, sup_ext[j].extensionName)) {
842 tstr = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
844 for (
int j = 0; j < sup_ext_count; j++) {
845 if (!strcmp(tstr, sup_ext[j].extensionName)) {
861 #ifdef VK_KHR_shader_relaxed_extended_instruction
864 tstr = VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME;
866 for (
int j = 0; j < sup_ext_count; j++) {
867 if (!strcmp(tstr, sup_ext[j].extensionName)) {
885 char *save, *token =
av_strtok(user_exts_str,
"+", &save);
888 for (
int j = 0; j < sup_ext_count; j++) {
889 if (!strcmp(token, sup_ext[j].extensionName)) {
905 *
dst = extension_names;
906 *num = extensions_found;
920 const char *
const **
dst, uint32_t *num,
927 static const char layer_standard_validation[] = {
"VK_LAYER_KHRONOS_validation" };
928 int layer_standard_validation_found = 0;
930 uint32_t sup_layer_count;
931 VkLayerProperties *sup_layers;
934 char *user_layers_str =
NULL;
937 const char **enabled_layers =
NULL;
938 uint32_t enabled_layers_count = 0;
946 vk->EnumerateInstanceLayerProperties(&sup_layer_count,
NULL);
947 sup_layers =
av_malloc_array(sup_layer_count,
sizeof(VkLayerProperties));
950 vk->EnumerateInstanceLayerProperties(&sup_layer_count, sup_layers);
953 for (
int i = 0;
i < sup_layer_count;
i++)
957 if (!debug_opt && !user_layers)
962 if (!strcmp(debug_opt->
value,
"profile")) {
964 }
else if (!strcmp(debug_opt->
value,
"printf")) {
966 }
else if (!strcmp(debug_opt->
value,
"validate")) {
968 }
else if (!strcmp(debug_opt->
value,
"practices")) {
971 char *end_ptr =
NULL;
972 int idx = strtol(debug_opt->
value, &end_ptr, 10);
973 if (end_ptr == debug_opt->
value || end_ptr[0] !=
'\0' ||
988 for (
int i = 0;
i < sup_layer_count;
i++) {
989 if (!strcmp(layer_standard_validation, sup_layers[
i].layerName)) {
991 layer_standard_validation);
992 ADD_VAL_TO_LIST(enabled_layers, enabled_layers_count, layer_standard_validation);
994 layer_standard_validation_found = 1;
998 if (!layer_standard_validation_found) {
1000 "Validation Layer \"%s\" not supported\n", layer_standard_validation);
1013 if (!user_layers_str) {
1018 token =
av_strtok(user_layers_str,
"+", &save);
1023 if (!strcmp(layer_standard_validation, token) && layer_standard_validation_found) {
1029 for (
int j = 0; j < sup_layer_count; j++) {
1030 if (!strcmp(token, sup_layers[j].layerName)) {
1041 if (!strcmp(layer_standard_validation, token))
1045 "Layer \"%s\" not supported\n", token);
1062 *
dst = enabled_layers;
1063 *num = enabled_layers_count;
1078 VkApplicationInfo application_info = {
1079 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
1080 .pApplicationName =
"ffmpeg",
1084 .pEngineName =
"libavutil",
1085 .apiVersion = VK_API_VERSION_1_3,
1090 VkValidationFeaturesEXT validation_features = {
1091 .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
1093 VkInstanceCreateInfo inst_props = {
1094 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
1095 .pApplicationInfo = &application_info,
1111 &inst_props.enabledLayerCount, debug_mode);
1117 &inst_props.enabledExtensionCount, *debug_mode);
1125 static const VkValidationFeatureEnableEXT feat_list_validate[] = {
1126 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1127 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1128 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
1130 validation_features.pEnabledValidationFeatures = feat_list_validate;
1131 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_validate);
1132 inst_props.pNext = &validation_features;
1134 static const VkValidationFeatureEnableEXT feat_list_debug[] = {
1135 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1136 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1137 VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT,
1139 validation_features.pEnabledValidationFeatures = feat_list_debug;
1140 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_debug);
1141 inst_props.pNext = &validation_features;
1143 static const VkValidationFeatureEnableEXT feat_list_practices[] = {
1144 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1145 VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT,
1147 validation_features.pEnabledValidationFeatures = feat_list_practices;
1148 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_practices);
1149 inst_props.pNext = &validation_features;
1153 for (
int i = 0;
i < inst_props.enabledExtensionCount;
i++) {
1154 if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
1155 inst_props.ppEnabledExtensionNames[
i])) {
1156 inst_props.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
1163 ret = vk->CreateInstance(&inst_props, hwctx->
alloc, &hwctx->
inst);
1166 if (
ret != VK_SUCCESS) {
1183 VkDebugUtilsMessengerCreateInfoEXT dbg = {
1184 .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
1185 .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
1186 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
1187 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
1188 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
1189 .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
1190 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
1191 VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
1196 vk->CreateDebugUtilsMessengerEXT(hwctx->
inst, &dbg,
1203 RELEASE_PROPS(inst_props.ppEnabledLayerNames, inst_props.enabledLayerCount);
1222 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
return "integrated";
1223 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
return "discrete";
1224 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
return "virtual";
1225 case VK_PHYSICAL_DEVICE_TYPE_CPU:
return "software";
1226 default:
return "unknown";
1233 int err = 0, choice = -1;
1239 VkPhysicalDevice *devices =
NULL;
1240 VkPhysicalDeviceIDProperties *idp =
NULL;
1241 VkPhysicalDeviceProperties2 *prop =
NULL;
1242 VkPhysicalDeviceDriverProperties *driver_prop =
NULL;
1243 VkPhysicalDeviceDrmPropertiesEXT *drm_prop =
NULL;
1245 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num,
NULL);
1246 if (
ret != VK_SUCCESS || !num) {
1255 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num, devices);
1256 if (
ret != VK_SUCCESS) {
1275 driver_prop =
av_calloc(num,
sizeof(*driver_prop));
1282 drm_prop =
av_calloc(num,
sizeof(*drm_prop));
1290 for (
int i = 0;
i < num;
i++) {
1292 drm_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT;
1293 driver_prop[
i].pNext = &drm_prop[
i];
1295 driver_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
1296 idp[
i].pNext = &driver_prop[
i];
1297 idp[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
1298 prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1299 prop[
i].pNext = &idp[
i];
1301 vk->GetPhysicalDeviceProperties2(devices[
i], &prop[
i]);
1303 prop[
i].properties.deviceName,
1305 prop[
i].properties.deviceID);
1309 for (
int i = 0;
i < num;
i++) {
1310 if (!strncmp(idp[
i].deviceUUID, select->
uuid, VK_UUID_SIZE)) {
1319 for (
int i = 0;
i < num;
i++) {
1320 if ((select->
drm_major == drm_prop[
i].primaryMajor &&
1321 select->
drm_minor == drm_prop[
i].primaryMinor) ||
1322 (select->
drm_major == drm_prop[
i].renderMajor &&
1323 select->
drm_minor == drm_prop[
i].renderMinor)) {
1332 }
else if (select->
name) {
1334 for (
int i = 0;
i < num;
i++) {
1335 if (strstr(prop[
i].properties.deviceName, select->
name)) {
1346 for (
int i = 0;
i < num;
i++) {
1347 if (select->
pci_device == prop[
i].properties.deviceID) {
1358 for (
int i = 0;
i < num;
i++) {
1359 if (select->
vendor_id == prop[
i].properties.vendorID) {
1369 if (select->
index < num) {
1370 choice = select->
index;
1382 choice, prop[choice].properties.deviceName,
1384 prop[choice].properties.deviceID);
1386 p->
props = prop[choice];
1388 p->
dprops = driver_prop[choice];
1403 VkQueueFlagBits
flags)
1406 uint32_t min_score = UINT32_MAX;
1408 for (
int i = 0;
i < num_qf;
i++) {
1409 VkQueueFlagBits qflags = qf[
i].queueFamilyProperties.queueFlags;
1412 if ((
flags & VK_QUEUE_TRANSFER_BIT) &&
1413 (qflags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)))
1414 qflags |= VK_QUEUE_TRANSFER_BIT;
1416 if (qflags &
flags) {
1417 uint32_t score =
av_popcount(qflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1418 if (score < min_score) {
1426 qf[
index].queueFamilyProperties.timestampValidBits++;
1432 VkQueueFamilyVideoPropertiesKHR *qf_vid, uint32_t num_qf,
1433 VkVideoCodecOperationFlagBitsKHR
flags)
1436 uint32_t min_score = UINT32_MAX;
1438 for (
int i = 0;
i < num_qf;
i++) {
1439 const VkQueueFlagBits qflags = qf[
i].queueFamilyProperties.queueFlags;
1440 const VkQueueFlagBits vflags = qf_vid[
i].videoCodecOperations;
1442 if (!(qflags & (VK_QUEUE_VIDEO_ENCODE_BIT_KHR | VK_QUEUE_VIDEO_DECODE_BIT_KHR)))
1445 if (vflags &
flags) {
1446 uint32_t score =
av_popcount(vflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1447 if (score < min_score) {
1455 qf[
index].queueFamilyProperties.timestampValidBits++;
1466 VkPhysicalDeviceDriverProperties dprops = {
1467 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES,
1469 VkPhysicalDeviceProperties2 props2 = {
1470 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
1474 VkQueueFamilyProperties2 *qf =
NULL;
1475 VkQueueFamilyVideoPropertiesKHR *qf_vid =
NULL;
1478 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &num,
NULL);
1489 qf_vid =
av_malloc_array(num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
1493 for (uint32_t
i = 0;
i < num;
i++) {
1494 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1495 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1497 qf[
i] = (VkQueueFamilyProperties2) {
1498 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
1504 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &num, qf);
1507 for (
int i = 0;
i < num;
i++) {
1509 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_GRAPHICS_BIT) ?
" graphics" :
"",
1510 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_COMPUTE_BIT) ?
" compute" :
"",
1511 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_TRANSFER_BIT) ?
" transfer" :
"",
1512 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ?
" encode" :
"",
1513 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_DECODE_BIT_KHR) ?
" decode" :
"",
1514 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_SPARSE_BINDING_BIT) ?
" sparse" :
"",
1515 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_OPTICAL_FLOW_BIT_NV) ?
" optical_flow" :
"",
1516 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_PROTECTED_BIT) ?
" protected" :
"",
1517 qf[
i].queueFamilyProperties.queueCount);
1521 qf[
i].queueFamilyProperties.timestampValidBits = 0;
1531 vk->GetPhysicalDeviceProperties2(hwctx->
phys_dev, &props2);
1534 #define PICK_QF(type, vid_op) \
1540 idx = pick_video_queue_family(qf, qf_vid, num, vid_op); \
1542 idx = pick_queue_family(qf, num, type); \
1547 for (i = 0; i < hwctx->nb_qf; i++) { \
1548 if (hwctx->qf[i].idx == idx) { \
1549 hwctx->qf[i].flags |= type; \
1550 hwctx->qf[i].video_caps |= vid_op; \
1554 if (i == hwctx->nb_qf) { \
1555 hwctx->qf[i].idx = idx; \
1556 hwctx->qf[i].num = qf[idx].queueFamilyProperties.queueCount; \
1557 if (p->limit_queues || \
1558 dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) { \
1559 int max = p->limit_queues; \
1560 if (type == VK_QUEUE_GRAPHICS_BIT) \
1561 hwctx->qf[i].num = FFMIN(hwctx->qf[i].num, \
1564 hwctx->qf[i].num = FFMIN(hwctx->qf[i].num, max); \
1566 hwctx->qf[i].flags = type; \
1567 hwctx->qf[i].video_caps = vid_op; \
1572 PICK_QF(VK_QUEUE_GRAPHICS_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1573 PICK_QF(VK_QUEUE_COMPUTE_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1574 PICK_QF(VK_QUEUE_TRANSFER_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1576 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR);
1577 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR);
1579 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR);
1580 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR);
1582 #ifdef VK_KHR_video_decode_vp9
1583 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR);
1586 #ifdef VK_KHR_video_encode_av1
1587 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR);
1589 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR);
1597 sizeof(VkDeviceQueueCreateInfo));
1598 if (!cd->pQueueCreateInfos)
1601 for (uint32_t
i = 0;
i < hwctx->
nb_qf;
i++) {
1604 VkDeviceQueueCreateInfo *pc;
1605 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++) {
1606 if (hwctx->
qf[
i].
idx == cd->pQueueCreateInfos[j].queueFamilyIndex) {
1616 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++)
1617 av_free((
void *)cd->pQueueCreateInfos[
i].pQueuePriorities);
1618 av_free((
void *)cd->pQueueCreateInfos);
1622 for (uint32_t j = 0; j < hwctx->
qf[
i].
num; j++)
1625 pc = (VkDeviceQueueCreateInfo *)cd->pQueueCreateInfos;
1626 pc[cd->queueCreateInfoCount++] = (VkDeviceQueueCreateInfo) {
1627 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1628 .queueFamilyIndex = hwctx->
qf[
i].
idx,
1629 .queueCount = hwctx->
qf[
i].
num,
1634 #if FF_API_VULKAN_FIXED_QUEUES
1643 #define SET_OLD_QF(field, nb_field, type) \
1645 if (field < 0 && hwctx->qf[i].flags & type) { \
1646 field = hwctx->qf[i].idx; \
1647 nb_field = hwctx->qf[i].num; \
1651 for (uint32_t
i = 0;
i < hwctx->
nb_qf;
i++) {
1681 vk->DestroyDebugUtilsMessengerEXT(hwctx->
inst, p->
debug_ctx,
1685 vk->DestroyInstance(hwctx->
inst, hwctx->
alloc);
1710 VkDeviceSize max_vram = 0, max_visible_vram = 0;
1713 for (
int i = 0;
i < p->
mprops.memoryTypeCount;
i++) {
1714 const VkMemoryType
type = p->
mprops.memoryTypes[
i];
1715 const VkMemoryHeap heap = p->
mprops.memoryHeaps[
type.heapIndex];
1716 if (!(
type.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
1718 max_vram =
FFMAX(max_vram, heap.size);
1719 if (
type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
1720 max_visible_vram =
FFMAX(max_visible_vram, heap.size);
1723 return max_vram - max_visible_vram < 1024;
1728 int disable_multiplane,
1739 VkDeviceCreateInfo dev_info = {
1740 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1753 &dev_info.enabledExtensionCount, debug_mode))) {
1754 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1755 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1756 av_free((
void *)dev_info.pQueueCreateInfos);
1761 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->
mprops);
1765 vk->GetPhysicalDeviceFeatures2(hwctx->
phys_dev, &supported_feats.
device);
1771 dev_info.pEnabledFeatures = &p->
feats.
device.features;
1781 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1782 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1783 av_free((
void *)dev_info.pQueueCreateInfos);
1785 if (
ret != VK_SUCCESS) {
1788 for (
int i = 0;
i < dev_info.enabledExtensionCount;
i++)
1789 av_free((
void *)dev_info.ppEnabledExtensionNames[
i]);
1790 av_free((
void *)dev_info.ppEnabledExtensionNames);
1846 VkQueueFamilyProperties2 *qf;
1847 VkQueueFamilyVideoPropertiesKHR *qf_vid;
1848 VkPhysicalDeviceExternalSemaphoreInfo ext_sem_props_info;
1849 int graph_index, comp_index, tx_index, enc_index, dec_index;
1868 p->
props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1870 p->
hprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;
1872 p->
dprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
1874 vk->GetPhysicalDeviceProperties2(hwctx->
phys_dev, &p->
props);
1876 p->
props.properties.deviceName);
1879 p->
props.properties.limits.optimalBufferCopyRowPitchAlignment);
1881 p->
props.properties.limits.minMemoryMapAlignment);
1883 p->
props.properties.limits.nonCoherentAtomSize);
1886 p->
hprops.minImportedHostPointerAlignment);
1890 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &qf_num,
NULL);
1896 ext_sem_props_info = (VkPhysicalDeviceExternalSemaphoreInfo) {
1897 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
1901 ext_sem_props_info.handleType =
1903 IsWindows8OrGreater()
1904 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
1905 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
1907 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
1910 vk->GetPhysicalDeviceExternalSemaphoreProperties(hwctx->
phys_dev,
1911 &ext_sem_props_info,
1918 qf_vid =
av_malloc_array(qf_num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
1924 for (uint32_t
i = 0;
i < qf_num;
i++) {
1925 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1926 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1928 qf[
i] = (VkQueueFamilyProperties2) {
1929 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
1934 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &qf_num, qf);
1943 for (uint32_t
i = 0;
i < qf_num;
i++) {
1950 for (uint32_t j = 0; j < qf[
i].queueFamilyProperties.queueCount; j++) {
1961 #if FF_API_VULKAN_FIXED_QUEUES
1969 #define CHECK_QUEUE(type, required, fidx, ctx_qf, qc) \
1971 if (ctx_qf < 0 && required) { \
1972 av_log(ctx, AV_LOG_ERROR, "%s queue family is required, but marked as missing" \
1973 " in the context!\n", type); \
1974 err = AVERROR(EINVAL); \
1976 } else if (fidx < 0 || ctx_qf < 0) { \
1978 } else if (ctx_qf >= qf_num) { \
1979 av_log(ctx, AV_LOG_ERROR, "Invalid %s family index %i (device has %i families)!\n", \
1980 type, ctx_qf, qf_num); \
1981 err = AVERROR(EINVAL); \
1985 av_log(ctx, AV_LOG_VERBOSE, "Using queue family %i (queues: %i)" \
1986 " for%s%s%s%s%s\n", \
1988 ctx_qf == graph_index ? " graphics" : "", \
1989 ctx_qf == comp_index ? " compute" : "", \
1990 ctx_qf == tx_index ? " transfers" : "", \
1991 ctx_qf == enc_index ? " encode" : "", \
1992 ctx_qf == dec_index ? " decode" : ""); \
1993 graph_index = (ctx_qf == graph_index) ? -1 : graph_index; \
1994 comp_index = (ctx_qf == comp_index) ? -1 : comp_index; \
1995 tx_index = (ctx_qf == tx_index) ? -1 : tx_index; \
1996 enc_index = (ctx_qf == enc_index) ? -1 : enc_index; \
1997 dec_index = (ctx_qf == dec_index) ? -1 : dec_index; \
2010 if (!hwctx->
nb_qf) {
2011 #define ADD_QUEUE(ctx_qf, qc, flag) \
2013 if (ctx_qf != -1) { \
2014 hwctx->qf[hwctx->nb_qf++] = (AVVulkanDeviceQueueFamily) { \
2032 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
2034 hwctx->
qf[
i].
flags & (VK_QUEUE_VIDEO_DECODE_BIT_KHR |
2035 VK_QUEUE_VIDEO_ENCODE_BIT_KHR)) {
2042 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
2046 for (
int j = (
i - 1); j >= 0; j--) {
2062 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->
mprops);
2072 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->
mprops);
2087 if (device && device[0]) {
2089 dev_select.
index = strtol(device, &end, 10);
2090 if (end == device) {
2091 dev_select.
index = 0;
2092 dev_select.
name = device;
2108 switch(src_ctx->
type) {
2112 VADisplay dpy = src_hwctx->
display;
2113 #if VA_CHECK_VERSION(1, 15, 0)
2115 VADisplayAttribute attr = {
2116 .type = VADisplayPCIID,
2121 #if VA_CHECK_VERSION(1, 15, 0)
2122 vas = vaGetDisplayAttributes(dpy, &attr, 1);
2123 if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED)
2124 dev_select.pci_device = (attr.value & 0xFFFF);
2127 if (!dev_select.pci_device) {
2128 vendor = vaQueryVendorString(dpy);
2134 if (strstr(vendor,
"AMD"))
2135 dev_select.vendor_id = 0x1002;
2144 struct stat drm_node_info;
2145 drmDevice *drm_dev_info;
2148 err = fstat(src_hwctx->
fd, &drm_node_info);
2155 dev_select.drm_major = major(drm_node_info.st_dev);
2156 dev_select.drm_minor = minor(drm_node_info.st_dev);
2157 dev_select.has_drm = 1;
2159 err = drmGetDevice(src_hwctx->
fd, &drm_dev_info);
2166 if (drm_dev_info->bustype == DRM_BUS_PCI)
2167 dev_select.pci_device = drm_dev_info->deviceinfo.pci->device_id;
2169 drmFreeDevice(&drm_dev_info);
2179 CudaFunctions *cu = cu_internal->
cuda_dl;
2181 int ret =
CHECK_CU(cu->cuDeviceGetUuid((CUuuid *)&dev_select.uuid,
2188 dev_select.has_uuid = 1;
2203 const void *hwconfig,
2212 VK_IMAGE_TILING_OPTIMAL,
2225 VK_IMAGE_TILING_OPTIMAL,
2235 constraints->
max_width = p->
props.properties.limits.maxImageDimension2D;
2236 constraints->
max_height = p->
props.properties.limits.maxImageDimension2D;
2249 VkMemoryPropertyFlagBits req_flags,
const void *alloc_extension,
2250 VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
2257 VkMemoryAllocateInfo alloc_info = {
2258 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2259 .pNext = alloc_extension,
2260 .allocationSize = req->size,
2265 for (
int i = 0;
i < p->
mprops.memoryTypeCount;
i++) {
2266 const VkMemoryType *
type = &p->
mprops.memoryTypes[
i];
2269 if (!(req->memoryTypeBits & (1 <<
i)))
2273 if ((
type->propertyFlags & req_flags) != req_flags)
2277 if (req->size > p->
mprops.memoryHeaps[
type->heapIndex].size)
2291 alloc_info.memoryTypeIndex =
index;
2293 ret = vk->AllocateMemory(dev_hwctx->
act_dev, &alloc_info,
2294 dev_hwctx->
alloc, mem);
2295 if (
ret != VK_SUCCESS) {
2301 *mem_flags |= p->
mprops.memoryTypes[
index].propertyFlags;
2311 if (internal->cuda_fc_ref) {
2317 CudaFunctions *cu = cu_internal->
cuda_dl;
2320 if (internal->cu_sem[
i])
2321 CHECK_CU(cu->cuDestroyExternalSemaphore(internal->cu_sem[
i]));
2322 if (internal->cu_mma[
i])
2323 CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[
i]));
2324 if (internal->ext_mem[
i])
2325 CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[
i]));
2327 if (internal->ext_sem_handle[
i])
2328 CloseHandle(internal->ext_sem_handle[
i]);
2329 if (internal->ext_mem_handle[
i])
2330 CloseHandle(internal->ext_mem_handle[
i]);
2355 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
2357 .pSemaphores =
f->sem,
2358 .pValues =
f->sem_value,
2359 .semaphoreCount = nb_sems,
2367 for (
int i = 0;
i < nb_images;
i++) {
2382 void *alloc_pnext,
size_t alloc_pnext_stride)
2384 int img_cnt = 0, err;
2392 while (
f->img[img_cnt]) {
2394 VkImageMemoryRequirementsInfo2 req_desc = {
2395 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
2396 .image =
f->img[img_cnt],
2398 VkMemoryDedicatedAllocateInfo ded_alloc = {
2399 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
2400 .pNext = (
void *)(((uint8_t *)alloc_pnext) + img_cnt*alloc_pnext_stride),
2402 VkMemoryDedicatedRequirements ded_req = {
2403 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
2405 VkMemoryRequirements2 req = {
2406 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
2410 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req);
2412 if (
f->tiling == VK_IMAGE_TILING_LINEAR)
2413 req.memoryRequirements.size =
FFALIGN(req.memoryRequirements.size,
2414 p->
props.properties.limits.minMemoryMapAlignment);
2417 use_ded_mem = ded_req.prefersDedicatedAllocation |
2418 ded_req.requiresDedicatedAllocation;
2420 ded_alloc.image =
f->img[img_cnt];
2424 f->tiling == VK_IMAGE_TILING_LINEAR ?
2425 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
2426 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2427 use_ded_mem ? &ded_alloc : (
void *)ded_alloc.pNext,
2428 &
f->flags, &
f->mem[img_cnt])))
2431 f->size[img_cnt] = req.memoryRequirements.size;
2432 bind_info[img_cnt].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
2433 bind_info[img_cnt].image =
f->img[img_cnt];
2434 bind_info[img_cnt].memory =
f->mem[img_cnt];
2440 ret = vk->BindImageMemory2(hwctx->
act_dev, img_cnt, bind_info);
2441 if (
ret != VK_SUCCESS) {
2470 VkImageLayout new_layout;
2471 VkAccessFlags2 new_access;
2472 VkPipelineStageFlagBits2 src_stage = VK_PIPELINE_STAGE_2_NONE;
2478 .
data = (uint8_t *)hwfc,
2482 .hw_frames_ctx = &tmp_ref,
2485 VkCommandBuffer cmd_buf;
2487 cmd_buf = exec->
buf;
2491 VK_PIPELINE_STAGE_2_NONE,
2492 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
2498 new_layout = VK_IMAGE_LAYOUT_GENERAL;
2499 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2502 new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
2503 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2506 new_layout = VK_IMAGE_LAYOUT_GENERAL;
2507 new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2510 new_layout = VK_IMAGE_LAYOUT_GENERAL;
2511 new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2512 dst_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR;
2513 src_stage = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
2516 new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR;
2517 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2520 new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR;
2521 new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2524 new_layout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR;
2525 new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2531 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
2532 new_access, new_layout, dst_qf);
2534 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
2535 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
2536 .pImageMemoryBarriers = img_bar,
2537 .imageMemoryBarrierCount = nb_img_bar,
2551 int frame_w,
int frame_h,
int plane)
2568 VkImageTiling tiling, VkImageUsageFlagBits
usage,
2569 VkImageCreateFlags
flags,
int nb_layers,
2581 VkSemaphoreTypeCreateInfo sem_type_info = {
2582 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2583 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2586 VkSemaphoreCreateInfo sem_spawn = {
2587 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2588 .pNext = &sem_type_info,
2591 VkExportSemaphoreCreateInfo ext_sem_info_opaque = {
2592 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
2594 .handleTypes = IsWindows8OrGreater()
2595 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2596 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
2598 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
2603 if (p->
ext_sem_props_opaque.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) {
2617 for (
int i = 0; (hwfc_vk->
format[
i] != VK_FORMAT_UNDEFINED);
i++) {
2618 VkImageCreateInfo create_info = {
2619 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2620 .pNext = create_pnext,
2621 .imageType = VK_IMAGE_TYPE_2D,
2625 .arrayLayers = nb_layers,
2628 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2630 .samples = VK_SAMPLE_COUNT_1_BIT,
2631 .pQueueFamilyIndices = p->
img_qfs,
2633 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2634 VK_SHARING_MODE_EXCLUSIVE,
2637 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
2640 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
2642 if (
ret != VK_SUCCESS) {
2650 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
2652 if (
ret != VK_SUCCESS) {
2660 f->layout[
i] = create_info.initialLayout;
2662 f->sem_value[
i] = 0;
2678 VkExternalMemoryHandleTypeFlags *comp_handle_types,
2679 VkExternalMemoryHandleTypeFlagBits *iexp,
2680 VkExternalMemoryHandleTypeFlagBits
exp)
2688 const VkImageDrmFormatModifierListCreateInfoEXT *drm_mod_info =
2690 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
2691 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && drm_mod_info;
2694 VkExternalImageFormatProperties eprops = {
2695 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
2697 VkImageFormatProperties2 props = {
2698 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
2701 VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
2702 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
2704 .pQueueFamilyIndices = p->
img_qfs,
2706 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2707 VK_SHARING_MODE_EXCLUSIVE,
2709 VkPhysicalDeviceExternalImageFormatInfo enext = {
2710 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
2712 .pNext = has_mods ? &phy_dev_mod_info :
NULL,
2714 VkPhysicalDeviceImageFormatInfo2 pinfo = {
2715 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
2716 .pNext = !
exp ?
NULL : &enext,
2718 .type = VK_IMAGE_TYPE_2D,
2720 .usage = hwctx->
usage,
2721 .flags = VK_IMAGE_CREATE_ALIAS_BIT,
2724 nb_mods = has_mods ? drm_mod_info->drmFormatModifierCount : 1;
2725 for (
int i = 0;
i < nb_mods;
i++) {
2727 phy_dev_mod_info.drmFormatModifier = drm_mod_info->pDrmFormatModifiers[
i];
2729 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
2732 if (
ret == VK_SUCCESS) {
2734 *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes;
2748 VkExternalMemoryHandleTypeFlags e = 0x0;
2751 VkExternalMemoryImageCreateInfo eiinfo = {
2752 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
2759 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
2760 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
2764 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
2767 hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
2769 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
2773 eminfo[
i].sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
2775 eminfo[
i].handleTypes = e;
2788 if ( (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2789 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR))
2791 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)
2793 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR)
2795 else if (hwctx->
usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)
2850 VkImageUsageFlagBits supported_usage;
2862 (hwctx->
tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
2863 hwctx->
tiling = VK_IMAGE_TILING_LINEAR;
2873 if (hwctx->
format[0] != VK_FORMAT_UNDEFINED) {
2878 "for the current sw_format %s!\n",
2890 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
2899 NULL, &supported_usage,
2902 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
2911 supported_usage &= ~VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
2914 if (!hwctx->
usage) {
2915 hwctx->
usage = supported_usage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT |
2916 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2917 VK_IMAGE_USAGE_STORAGE_BIT |
2918 VK_IMAGE_USAGE_SAMPLED_BIT);
2921 hwctx->
usage |= supported_usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
2924 if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
2927 hwctx->
usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
2934 int is_lone_dpb = ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR) ||
2935 ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2936 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)));
2937 int sampleable = hwctx->
usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
2938 VK_IMAGE_USAGE_STORAGE_BIT);
2939 hwctx->
img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
2940 if (sampleable && !is_lone_dpb) {
2941 hwctx->
img_flags |= VK_IMAGE_CREATE_ALIAS_BIT;
2943 hwctx->
img_flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
2951 if ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
2954 const VkVideoProfileListInfoKHR *pl;
2957 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
2960 for (
i = 0;
i < pl->profileCount;
i++) {
2962 if (pl->pProfiles[
i].videoCodecOperation & 0xFFFF0000)
2965 if (
i == pl->profileCount)
2966 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
2999 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
3000 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
3002 err = vk->GetImageDrmFormatModifierPropertiesEXT(dev_hwctx->
act_dev,
f->img[0],
3004 if (err != VK_SUCCESS) {
3010 VkDrmFormatModifierPropertiesListEXT modp;
3011 VkFormatProperties2 fmtp;
3012 VkDrmFormatModifierPropertiesEXT *mod_props =
NULL;
3014 modp = (VkDrmFormatModifierPropertiesListEXT) {
3015 .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
3017 fmtp = (VkFormatProperties2) {
3018 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
3023 vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->
phys_dev, fmt->
fallback[
i], &fmtp);
3025 modp.pDrmFormatModifierProperties =
3026 av_calloc(modp.drmFormatModifierCount,
sizeof(*modp.pDrmFormatModifierProperties));
3027 if (!modp.pDrmFormatModifierProperties) {
3031 vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->
phys_dev, fmt->
fallback[
i], &fmtp);
3033 for (uint32_t
i = 0;
i < modp.drmFormatModifierCount; ++
i) {
3034 VkDrmFormatModifierPropertiesEXT *m = &modp.pDrmFormatModifierProperties[
i];
3035 if (m->drmFormatModifier == drm_mod.drmFormatModifier) {
3041 if (mod_props ==
NULL) {
3042 av_log(hwfc,
AV_LOG_ERROR,
"No DRM format modifier properties found for modifier 0x%016"PRIx64
"\n",
3043 drm_mod.drmFormatModifier);
3044 av_free(modp.pDrmFormatModifierProperties);
3050 av_free(modp.pDrmFormatModifierProperties);
3114 static const struct {
3115 uint32_t drm_fourcc;
3117 } vulkan_drm_format_map[] = {
3118 { DRM_FORMAT_R8, VK_FORMAT_R8_UNORM },
3119 { DRM_FORMAT_R16, VK_FORMAT_R16_UNORM },
3120 { DRM_FORMAT_GR88, VK_FORMAT_R8G8_UNORM },
3121 { DRM_FORMAT_RG88, VK_FORMAT_R8G8_UNORM },
3122 { DRM_FORMAT_GR1616, VK_FORMAT_R16G16_UNORM },
3123 { DRM_FORMAT_RG1616, VK_FORMAT_R16G16_UNORM },
3124 { DRM_FORMAT_ARGB8888, VK_FORMAT_B8G8R8A8_UNORM },
3125 { DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM },
3126 { DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM },
3127 { DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM },
3128 { DRM_FORMAT_ARGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
3129 { DRM_FORMAT_ABGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
3130 { DRM_FORMAT_XRGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
3131 { DRM_FORMAT_XBGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
3134 #ifdef DRM_FORMAT_XYUV8888
3135 { DRM_FORMAT_XYUV8888, VK_FORMAT_R8G8B8A8_UNORM },
3136 { DRM_FORMAT_XVYU2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 } ,
3137 { DRM_FORMAT_XVYU12_16161616, VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 } ,
3138 { DRM_FORMAT_XVYU16161616, VK_FORMAT_R16G16B16A16_UNORM } ,
3142 static inline VkFormat drm_to_vulkan_fmt(uint32_t drm_fourcc)
3145 if (vulkan_drm_format_map[
i].drm_fourcc == drm_fourcc)
3146 return vulkan_drm_format_map[
i].vk_format;
3147 return VK_FORMAT_UNDEFINED;
3156 int bind_counts = 0;
3166 if (drm_to_vulkan_fmt(
desc->layers[
i].format) == VK_FORMAT_UNDEFINED) {
3168 desc->layers[
i].format);
3179 f->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
3181 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3185 VkSemaphoreTypeCreateInfo sem_type_info = {
3186 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3187 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
3190 VkSemaphoreCreateInfo sem_spawn = {
3191 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3192 .pNext = &sem_type_info,
3197 VkImageDrmFormatModifierExplicitCreateInfoEXT ext_img_mod_spec = {
3198 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
3199 .drmFormatModifier =
desc->objects[0].format_modifier,
3200 .drmFormatModifierPlaneCount =
planes,
3201 .pPlaneLayouts = (
const VkSubresourceLayout *)&ext_img_layouts,
3203 VkExternalMemoryImageCreateInfo ext_img_spec = {
3204 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
3205 .pNext = &ext_img_mod_spec,
3206 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3208 VkImageCreateInfo create_info = {
3209 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3210 .pNext = &ext_img_spec,
3211 .imageType = VK_IMAGE_TYPE_2D,
3212 .format = drm_to_vulkan_fmt(
desc->layers[
i].format),
3217 .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
3218 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
3220 .samples = VK_SAMPLE_COUNT_1_BIT,
3221 .pQueueFamilyIndices = p->
img_qfs,
3223 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
3224 VK_SHARING_MODE_EXCLUSIVE,
3228 VkExternalImageFormatProperties ext_props = {
3229 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
3231 VkImageFormatProperties2 props_ret = {
3232 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
3233 .pNext = &ext_props,
3235 VkPhysicalDeviceImageDrmFormatModifierInfoEXT props_drm_mod = {
3236 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
3237 .drmFormatModifier = ext_img_mod_spec.drmFormatModifier,
3238 .pQueueFamilyIndices = create_info.pQueueFamilyIndices,
3239 .queueFamilyIndexCount = create_info.queueFamilyIndexCount,
3240 .sharingMode = create_info.sharingMode,
3242 VkPhysicalDeviceExternalImageFormatInfo props_ext = {
3243 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
3244 .pNext = &props_drm_mod,
3245 .handleType = ext_img_spec.handleTypes,
3247 VkPhysicalDeviceImageFormatInfo2 fmt_props;
3250 create_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT |
3251 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3253 create_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT |
3254 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3256 fmt_props = (VkPhysicalDeviceImageFormatInfo2) {
3257 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3258 .pNext = &props_ext,
3259 .format = create_info.format,
3260 .type = create_info.imageType,
3261 .tiling = create_info.tiling,
3262 .usage = create_info.usage,
3263 .flags = create_info.flags,
3267 ret = vk->GetPhysicalDeviceImageFormatProperties2(hwctx->
phys_dev,
3268 &fmt_props, &props_ret);
3269 if (
ret != VK_SUCCESS) {
3277 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
3281 for (
int j = 0; j <
planes; j++) {
3282 ext_img_layouts[j].offset =
desc->layers[
i].planes[j].offset;
3283 ext_img_layouts[j].rowPitch =
desc->layers[
i].planes[j].pitch;
3284 ext_img_layouts[j].size = 0;
3285 ext_img_layouts[j].arrayPitch = 0;
3286 ext_img_layouts[j].depthPitch = 0;
3290 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
3292 if (
ret != VK_SUCCESS) {
3299 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3301 if (
ret != VK_SUCCESS) {
3308 f->queue_family[
i] = VK_QUEUE_FAMILY_EXTERNAL;
3309 f->layout[
i] = create_info.initialLayout;
3311 f->sem_value[
i] = 0;
3314 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3316 VkImageMemoryRequirementsInfo2 req_desc = {
3317 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
3320 VkMemoryDedicatedRequirements ded_req = {
3321 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
3323 VkMemoryRequirements2 req2 = {
3324 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3329 VkMemoryFdPropertiesKHR fdmp = {
3330 .sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR,
3336 VkImportMemoryFdInfoKHR idesc = {
3337 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
3338 .fd = dup(
desc->objects[
desc->layers[
i].planes[0].object_index].fd),
3339 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3341 VkMemoryDedicatedAllocateInfo ded_alloc = {
3342 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
3344 .image = req_desc.image,
3348 ret = vk->GetMemoryFdPropertiesKHR(hwctx->
act_dev,
3349 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3351 if (
ret != VK_SUCCESS) {
3359 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req2);
3362 req2.memoryRequirements.memoryTypeBits = fdmp.memoryTypeBits;
3365 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
3366 (ded_req.prefersDedicatedAllocation ||
3367 ded_req.requiresDedicatedAllocation) ?
3368 &ded_alloc : ded_alloc.pNext,
3369 &
f->flags, &
f->mem[
i]);
3375 f->size[
i] = req2.memoryRequirements.size;
3378 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3380 for (
int j = 0; j <
planes; j++) {
3381 VkImageAspectFlagBits aspect = j == 0 ? VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT :
3382 j == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3383 VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
3385 plane_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO;
3387 plane_info[bind_counts].planeAspect = aspect;
3389 bind_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
3391 bind_info[bind_counts].image =
f->img[
i];
3392 bind_info[bind_counts].memory =
f->mem[
i];
3395 bind_info[bind_counts].memoryOffset = 0;
3402 ret = vk->BindImageMemory2(hwctx->
act_dev, bind_counts, bind_info);
3403 if (
ret != VK_SUCCESS) {
3433 #ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
3435 VkCommandBuffer cmd_buf;
3441 for (
int i = 0;
i <
desc->nb_objects;
i++) {
3442 VkSemaphoreTypeCreateInfo sem_type_info = {
3443 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3444 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
3446 VkSemaphoreCreateInfo sem_spawn = {
3447 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3448 .pNext = &sem_type_info,
3450 VkImportSemaphoreFdInfoKHR import_info;
3451 struct dma_buf_export_sync_file implicit_fd_info = {
3452 .flags = DMA_BUF_SYNC_READ,
3456 if (ioctl(
desc->objects[
i].fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE,
3457 &implicit_fd_info)) {
3462 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3466 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3467 hwctx->
alloc, &drm_sync_sem[
i]);
3468 if (
ret != VK_SUCCESS) {
3473 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3477 import_info = (VkImportSemaphoreFdInfoKHR) {
3478 .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
3479 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
3480 .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
3481 .semaphore = drm_sync_sem[
i],
3482 .fd = implicit_fd_info.fd,
3485 ret = vk->ImportSemaphoreFdKHR(hwctx->
act_dev, &import_info);
3486 if (
ret != VK_SUCCESS) {
3491 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3497 cmd_buf = exec->
buf;
3503 drm_sync_sem,
desc->nb_objects,
3504 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 1);
3509 VK_PIPELINE_STAGE_2_NONE,
3510 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
3515 VK_PIPELINE_STAGE_2_NONE,
3516 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
3518 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT : 0x0) |
3520 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT : 0x0),
3521 VK_IMAGE_LAYOUT_GENERAL,
3524 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
3525 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
3526 .pImageMemoryBarriers = img_bar,
3527 .imageMemoryBarrierCount = nb_img_bar,
3538 "image may be corrupted.\n");
3553 if ((err = vulkan_map_from_drm_frame_desc(hwfc, &
f,
src,
flags)))
3557 dst->data[0] = (uint8_t *)
f;
3559 dst->height =
src->height;
3562 &vulkan_unmap_from_drm,
f);
3566 err = vulkan_map_from_drm_frame_sync(hwfc,
dst,
src,
flags);
3589 VASurfaceID surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
3595 vaSyncSurface(vaapi_ctx->display, surface_id);
3603 err = vulkan_map_from_drm(dst_fc,
dst,
tmp,
flags);
3620 VkDeviceMemory mem,
size_t size)
3628 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3629 .type = IsWindows8OrGreater()
3630 ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
3631 : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT,
3634 VkMemoryGetWin32HandleInfoKHR export_info = {
3635 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
3637 .handleType = IsWindows8OrGreater()
3638 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
3639 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
3642 ret = vk->GetMemoryWin32HandleKHR(hwctx->
act_dev, &export_info,
3643 &ext_desc.handle.win32.handle);
3644 if (
ret != VK_SUCCESS) {
3649 dst_int->ext_mem_handle[idx] = ext_desc.handle.win32.handle;
3651 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3652 .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
3655 VkMemoryGetFdInfoKHR export_info = {
3656 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
3658 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
3661 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
3662 &ext_desc.handle.fd);
3663 if (
ret != VK_SUCCESS) {
3670 ret =
CHECK_CU(cu->cuImportExternalMemory(&dst_int->ext_mem[idx], &ext_desc));
3673 close(ext_desc.handle.fd);
3692 VkSemaphoreGetWin32HandleInfoKHR sem_export = {
3693 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
3695 .handleType = IsWindows8OrGreater()
3696 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
3697 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
3699 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3703 VkSemaphoreGetFdInfoKHR sem_export = {
3704 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
3706 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
3708 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3714 ret = vk->GetSemaphoreWin32HandleKHR(hwctx->
act_dev, &sem_export,
3715 &ext_sem_desc.handle.win32.handle);
3717 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &sem_export,
3718 &ext_sem_desc.handle.fd);
3720 if (
ret != VK_SUCCESS) {
3726 dst_int->ext_sem_handle[idx] = ext_sem_desc.handle.win32.handle;
3729 ret =
CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[idx],
3733 close(ext_sem_desc.handle.fd);
3761 CudaFunctions *cu = cu_internal->
cuda_dl;
3762 CUarray_format cufmt =
desc->comp[0].depth > 8 ? CU_AD_FORMAT_UNSIGNED_INT16 :
3763 CU_AD_FORMAT_UNSIGNED_INT8;
3768 if (!dst_int->cuda_fc_ref) {
3772 if (!dst_int->cuda_fc_ref)
3776 for (
int i = 0;
i < nb_images;
i++) {
3777 err = export_mem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
3782 err = export_sem_to_cuda(
ctx, cuda_cu, cu, dst_int,
i,
3788 if (nb_images !=
planes) {
3790 VkImageSubresource subres = {
3791 .aspectMask =
i == 2 ? VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT :
3792 i == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3793 VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT
3795 VkSubresourceLayout
layout = { 0 };
3796 vk->GetImageSubresourceLayout(hwctx->
act_dev, dst_f->
img[
FFMIN(
i, nb_images - 1)],
3803 CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = {
3808 .NumChannels = 1 + ((
planes == 2) &&
i),
3816 tex_desc.arrayDesc.Width = p_w;
3817 tex_desc.arrayDesc.Height = p_h;
3819 ret =
CHECK_CU(cu->cuExternalMemoryGetMappedMipmappedArray(&dst_int->cu_mma[
i],
3820 dst_int->ext_mem[
FFMIN(
i, nb_images - 1)],
3827 ret =
CHECK_CU(cu->cuMipmappedArrayGetLevel(&dst_int->cu_array[
i],
3828 dst_int->cu_mma[
i], 0));
3859 CudaFunctions *cu = cu_internal->
cuda_dl;
3869 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
3873 err = vulkan_export_to_cuda(hwfc,
src->hw_frames_ctx,
dst);
3882 s_w_par[
i].params.fence.value = dst_f->
sem_value[
i] + 0;
3883 s_s_par[
i].params.fence.value = dst_f->
sem_value[
i] + 1;
3886 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
3887 planes, cuda_dev->stream));
3892 CUDA_MEMCPY2D cpy = {
3893 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
3894 .srcDevice = (CUdeviceptr)
src->data[
i],
3895 .srcPitch =
src->linesize[
i],
3898 .dstMemoryType = CU_MEMORYTYPE_ARRAY,
3899 .dstArray = dst_int->cu_array[
i],
3905 cpy.WidthInBytes = p_w *
desc->comp[
i].step;
3908 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
3913 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
3914 planes, cuda_dev->stream));
3940 switch (
src->format) {
3945 return vulkan_map_from_vaapi(hwfc,
dst,
src,
flags);
3951 return vulkan_map_from_drm(hwfc,
dst,
src,
flags);
3961 typedef struct VulkanDRMMapping {
3976 static inline uint32_t vulkan_fmt_to_drm(
VkFormat vkfmt)
3979 if (vulkan_drm_format_map[
i].vk_format == vkfmt)
3980 return vulkan_drm_format_map[
i].drm_fourcc;
3981 return DRM_FORMAT_INVALID;
3984 #define MAX_MEMORY_PLANES 4
3985 static VkImageAspectFlags plane_index_to_aspect(
int plane) {
3986 if (plane == 0)
return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
3987 if (plane == 1)
return VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT;
3988 if (plane == 2)
return VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
3989 if (plane == 3)
return VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT;
3992 return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
4006 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
4007 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
4009 VkSemaphoreWaitInfo wait_info = {
4010 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
4012 .semaphoreCount =
planes,
4024 wait_info.pSemaphores =
f->sem;
4025 wait_info.pValues =
f->sem_value;
4027 vk->WaitSemaphores(hwctx->
act_dev, &wait_info, UINT64_MAX);
4033 ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->
act_dev,
f->img[0],
4035 if (
ret != VK_SUCCESS) {
4041 for (
int i = 0; (
i <
planes) && (
f->mem[
i]);
i++) {
4042 VkMemoryGetFdInfoKHR export_info = {
4043 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
4044 .memory =
f->mem[
i],
4045 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
4048 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
4050 if (
ret != VK_SUCCESS) {
4065 drm_desc->
layers[
i].
format = vulkan_fmt_to_drm(plane_vkfmt);
4075 VkSubresourceLayout
layout;
4076 VkImageSubresource sub = {
4077 .aspectMask = plane_index_to_aspect(j),
4082 vk->GetImageSubresourceLayout(hwctx->
act_dev,
f->img[
i], &sub, &
layout);
4094 if (
f->tiling == VK_IMAGE_TILING_OPTIMAL)
4100 dst->height =
src->height;
4101 dst->data[0] = (uint8_t *)drm_desc;
4145 switch (
dst->format) {
4155 return vulkan_map_to_vaapi(hwfc,
dst,
src,
flags);
4167 AVFrame *swf, VkBufferImageCopy *region,
4177 const VkMappedMemoryRange flush_info = {
4178 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
4179 .memory = vkbuf->
mem,
4180 .size = VK_WHOLE_SIZE,
4183 if (!upload && !(vkbuf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
4184 ret = vk->InvalidateMappedMemoryRanges(hwctx->
act_dev, 1,
4186 if (
ret != VK_SUCCESS) {
4196 region[
i].bufferRowLength,
4200 region[
i].imageExtent.height);
4205 vkbuf->mapped_mem + region[
i].bufferOffset,
4206 region[
i].bufferRowLength,
4208 region[
i].imageExtent.height);
4211 if (upload && !(vkbuf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
4212 ret = vk->FlushMappedMemoryRanges(hwctx->
act_dev, 1,
4214 if (
ret != VK_SUCCESS) {
4225 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4232 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4233 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4235 size_t buf_offset = 0;
4239 region[
i] = (VkBufferImageCopy) {
4240 .bufferOffset = buf_offset,
4242 p->
props.properties.limits.optimalBufferCopyRowPitchAlignment),
4243 .bufferImageHeight = p_h,
4244 .imageSubresource.layerCount = 1,
4245 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4249 buf_offset +=
FFALIGN(p_h*region[
i].bufferRowLength,
4250 p->
props.properties.limits.optimalBufferCopyOffsetAlignment);
4255 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
4256 VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
4264 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4271 VkBufferUsageFlags buf_usage = upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4272 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4281 while (swf->
buf[nb_src_bufs])
4285 if (nb_src_bufs == 1) {
4296 }
else if (nb_src_bufs ==
planes) {
4315 for (
int i = 0;
i < (*nb_bufs);
i++)
4335 int nb_layout_ch = 0;
4339 for (
int i = 0;
i < nb_images;
i++) {
4350 layout_ch_info[nb_layout_ch] = (VkHostImageLayoutTransitionInfoEXT) {
4351 .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT,
4352 .image = hwf_vk->
img[
i],
4353 .oldLayout = hwf_vk->
layout[
i],
4354 .newLayout = VK_IMAGE_LAYOUT_GENERAL,
4355 .subresourceRange = {
4356 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4362 hwf_vk->
layout[
i] = layout_ch_info[nb_layout_ch].newLayout;
4367 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
4368 .pSemaphores = hwf_vk->
sem,
4370 .semaphoreCount = nb_images,
4376 vk->TransitionImageLayoutEXT(hwctx->
act_dev,
4377 nb_layout_ch, layout_ch_info);
4380 VkMemoryToImageCopyEXT region_info = {
4381 .sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT,
4382 .imageSubresource = {
4386 VkCopyMemoryToImageInfoEXT copy_info = {
4387 .sType = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT,
4388 .flags = VK_HOST_IMAGE_COPY_MEMCPY_EXT,
4390 .pRegions = ®ion_info,
4393 int img_idx =
FFMIN(
i, (nb_images - 1));
4397 region_info.pHostPointer = swf->
data[
i];
4399 region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 };
4400 copy_info.dstImage = hwf_vk->
img[img_idx];
4401 copy_info.dstImageLayout = hwf_vk->
layout[img_idx];
4403 vk->CopyMemoryToImageEXT(hwctx->
act_dev, ©_info);
4406 VkImageToMemoryCopyEXT region_info = {
4407 .sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT,
4408 .imageSubresource = {
4412 VkCopyImageToMemoryInfoEXT copy_info = {
4413 .sType = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT,
4414 .flags = VK_HOST_IMAGE_COPY_MEMCPY_EXT,
4416 .pRegions = ®ion_info,
4419 int img_idx =
FFMIN(
i, (nb_images - 1));
4423 region_info.pHostPointer = swf->
data[
i];
4425 region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 };
4426 copy_info.srcImage = hwf_vk->
img[img_idx];
4427 copy_info.srcImageLayout = hwf_vk->
layout[img_idx];
4429 vk->CopyImageToMemoryEXT(hwctx->
act_dev, ©_info);
4448 int host_mapped = 0;
4463 VkCommandBuffer cmd_buf;
4475 if (hwctx->
usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT)
4483 region[
i] = (VkBufferImageCopy) {
4486 .bufferImageHeight = p_h,
4487 .imageSubresource.layerCount = 1,
4488 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4514 cmd_buf = exec->
buf;
4520 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
4521 VK_PIPELINE_STAGE_2_TRANSFER_BIT);
4545 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
4546 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,
4547 upload ? VK_ACCESS_TRANSFER_WRITE_BIT :
4548 VK_ACCESS_TRANSFER_READ_BIT,
4549 upload ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL :
4550 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4553 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
4554 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
4555 .pImageMemoryBarriers = img_bar,
4556 .imageMemoryBarrierCount = nb_img_bar,
4560 int buf_idx =
FFMIN(
i, (nb_bufs - 1));
4561 int img_idx =
FFMIN(
i, (nb_images - 1));
4564 uint32_t orig_stride = region[
i].bufferRowLength;
4565 region[
i].bufferRowLength /=
desc->comp[
i].step;
4569 vk->CmdCopyBufferToImage(cmd_buf, vkbuf->
buf,
4570 hwf_vk->
img[img_idx],
4571 img_bar[img_idx].newLayout,
4574 vk->CmdCopyImageToBuffer(cmd_buf, hwf_vk->
img[img_idx],
4575 img_bar[img_idx].newLayout,
4579 region[
i].bufferRowLength = orig_stride;
4585 }
else if (!upload) {
4592 for (
int i = 0;
i < nb_bufs;
i++)
4603 switch (
src->format) {
4613 return vulkan_transfer_data_from_cuda(hwfc,
dst,
src);
4616 if (
src->hw_frames_ctx)
4640 CudaFunctions *cu = cu_internal->
cuda_dl;
4651 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
4655 err = vulkan_export_to_cuda(hwfc,
dst->hw_frames_ctx,
src);
4664 s_w_par[
i].params.fence.value = dst_f->
sem_value[
i] + 0;
4665 s_s_par[
i].params.fence.value = dst_f->
sem_value[
i] + 1;
4668 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
4669 nb_images, cuda_dev->stream));
4674 CUDA_MEMCPY2D cpy = {
4675 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
4676 .dstDevice = (CUdeviceptr)
dst->data[
i],
4677 .dstPitch =
dst->linesize[
i],
4680 .srcMemoryType = CU_MEMORYTYPE_ARRAY,
4681 .srcArray = dst_int->cu_array[
i],
4687 cpy.WidthInBytes =
w *
desc->comp[
i].step;
4690 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
4695 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
4696 nb_images, cuda_dev->stream));
4722 switch (
dst->format) {
4732 return vulkan_transfer_data_to_cuda(hwfc,
dst,
src);
4735 if (
dst->hw_frames_ctx)