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)
92 #ifdef VK_KHR_shader_relaxed_extended_instruction
93 VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR relaxed_extended_instruction;
113 VkPhysicalDeviceExternalMemoryHostPropertiesEXT
hprops;
183 #define OPT_CHAIN(STRUCT_P, EXT_FLAG, TYPE) \
185 if ((EXT_FLAG == FF_VK_EXT_NO_FLAG) || \
186 (p->vkctx.extensions & EXT_FLAG)) { \
187 (STRUCT_P)->sType = TYPE; \
188 ff_vk_link_struct(&feats->device, STRUCT_P); \
192 feats->
device = (VkPhysicalDeviceFeatures2) {
193 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
197 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES);
199 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES);
201 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES);
204 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES);
207 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR);
210 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);
212 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR);
214 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT);
216 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT);
218 #ifdef VK_KHR_shader_relaxed_extended_instruction
220 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR);
224 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV);
231 #define COPY_VAL(VAL) \
233 dst->VAL = src->VAL; \
236 COPY_VAL(device.features.shaderImageGatherExtended);
237 COPY_VAL(device.features.shaderStorageImageReadWithoutFormat);
238 COPY_VAL(device.features.shaderStorageImageWriteWithoutFormat);
239 COPY_VAL(device.features.fragmentStoresAndAtomics);
240 COPY_VAL(device.features.vertexPipelineStoresAndAtomics);
241 COPY_VAL(device.features.shaderInt64);
242 COPY_VAL(device.features.shaderInt16);
243 COPY_VAL(device.features.shaderFloat64);
245 COPY_VAL(vulkan_1_1.samplerYcbcrConversion);
246 COPY_VAL(vulkan_1_1.storagePushConstant16);
247 COPY_VAL(vulkan_1_1.storageBuffer16BitAccess);
248 COPY_VAL(vulkan_1_1.uniformAndStorageBuffer16BitAccess);
250 COPY_VAL(vulkan_1_2.timelineSemaphore);
251 COPY_VAL(vulkan_1_2.scalarBlockLayout);
252 COPY_VAL(vulkan_1_2.bufferDeviceAddress);
253 COPY_VAL(vulkan_1_2.hostQueryReset);
254 COPY_VAL(vulkan_1_2.storagePushConstant8);
256 COPY_VAL(vulkan_1_2.storageBuffer8BitAccess);
257 COPY_VAL(vulkan_1_2.uniformAndStorageBuffer8BitAccess);
259 COPY_VAL(vulkan_1_2.shaderBufferInt64Atomics);
260 COPY_VAL(vulkan_1_2.shaderSharedInt64Atomics);
261 COPY_VAL(vulkan_1_2.vulkanMemoryModel);
262 COPY_VAL(vulkan_1_2.vulkanMemoryModelDeviceScope);
264 COPY_VAL(vulkan_1_3.dynamicRendering);
266 COPY_VAL(vulkan_1_3.synchronization2);
267 COPY_VAL(vulkan_1_3.computeFullSubgroups);
268 COPY_VAL(vulkan_1_3.shaderZeroInitializeWorkgroupMemory);
269 COPY_VAL(vulkan_1_3.dynamicRendering);
271 COPY_VAL(timeline_semaphore.timelineSemaphore);
273 COPY_VAL(video_maintenance_1.videoMaintenance1);
275 COPY_VAL(shader_object.shaderObject);
277 COPY_VAL(cooperative_matrix.cooperativeMatrix);
279 COPY_VAL(descriptor_buffer.descriptorBuffer);
280 COPY_VAL(descriptor_buffer.descriptorBufferPushDescriptors);
282 COPY_VAL(atomic_float.shaderBufferFloat32Atomics);
283 COPY_VAL(atomic_float.shaderBufferFloat32AtomicAdd);
285 #ifdef VK_KHR_shader_relaxed_extended_instruction
286 COPY_VAL(relaxed_extended_instruction.shaderRelaxedExtendedInstruction);
293 #define ASPECT_2PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT)
294 #define ASPECT_3PLANE (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)
306 { VK_FORMAT_R8_UNORM,
AV_PIX_FMT_GRAY8, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8_UNORM } },
307 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
308 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY12, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
309 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY14, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
310 { VK_FORMAT_R16_UNORM,
AV_PIX_FMT_GRAY16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16_UNORM } },
311 { VK_FORMAT_R32_SFLOAT,
AV_PIX_FMT_GRAYF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_SFLOAT } },
314 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_BGRA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
315 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGBA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
316 { VK_FORMAT_R8G8B8_UNORM,
AV_PIX_FMT_RGB24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8_UNORM } },
317 { VK_FORMAT_B8G8R8_UNORM,
AV_PIX_FMT_BGR24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8_UNORM } },
318 { VK_FORMAT_R16G16B16_UNORM,
AV_PIX_FMT_RGB48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16_UNORM } },
319 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_RGBA64, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
320 { VK_FORMAT_R5G6B5_UNORM_PACK16,
AV_PIX_FMT_RGB565, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R5G6B5_UNORM_PACK16 } },
321 { VK_FORMAT_B5G6R5_UNORM_PACK16,
AV_PIX_FMT_BGR565, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B5G6R5_UNORM_PACK16 } },
322 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_BGR0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
323 { VK_FORMAT_R8G8B8A8_UNORM,
AV_PIX_FMT_RGB0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
324 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_X2RGB10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
325 { VK_FORMAT_A2B10G10R10_UNORM_PACK32,
AV_PIX_FMT_X2BGR10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2B10G10R10_UNORM_PACK32 } },
326 { VK_FORMAT_R32G32B32_SFLOAT,
AV_PIX_FMT_RGBF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_SFLOAT } },
327 { VK_FORMAT_R32G32B32A32_SFLOAT,
AV_PIX_FMT_RGBAF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_SFLOAT } },
328 { VK_FORMAT_R32G32B32_UINT,
AV_PIX_FMT_RGB96, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32_UINT } },
329 { VK_FORMAT_R32G32B32A32_UINT,
AV_PIX_FMT_RGBA128, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_UINT } },
332 { 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 } },
333 { 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 } },
334 { 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 } },
335 { 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 } },
336 { 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 } },
339 { 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 } },
340 { 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 } },
341 { 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 } },
342 { 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 } },
343 { 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 } },
344 { 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 } },
348 { 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 } },
349 { 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 } },
354 { 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 } },
355 { 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 } },
360 { 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 } },
361 { 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 } },
379 { VK_FORMAT_G8B8G8R8_422_UNORM,
AV_PIX_FMT_YUYV422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
380 { VK_FORMAT_B8G8R8G8_422_UNORM,
AV_PIX_FMT_UYVY422, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
381 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
AV_PIX_FMT_Y210, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
382 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
AV_PIX_FMT_Y212, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
383 { VK_FORMAT_G16B16G16R16_422_UNORM,
AV_PIX_FMT_Y216, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
386 { VK_FORMAT_B8G8R8A8_UNORM,
AV_PIX_FMT_UYVA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
387 { VK_FORMAT_A2R10G10B10_UNORM_PACK32,
AV_PIX_FMT_XV30, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
388 { VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
AV_PIX_FMT_XV36, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
389 { VK_FORMAT_R16G16B16A16_UNORM,
AV_PIX_FMT_XV48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
410 #define FN_MAP_TO(dst_t, dst_name, src_t, src_name) \
411 static av_unused dst_t map_ ##src_name## _to_ ##dst_name(src_t src) \
414 MAP_TO(VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT, \
415 VK_IMAGE_USAGE_SAMPLED_BIT); \
416 MAP_TO(VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT, \
417 VK_IMAGE_USAGE_TRANSFER_SRC_BIT); \
418 MAP_TO(VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT, \
419 VK_IMAGE_USAGE_TRANSFER_DST_BIT); \
420 MAP_TO(VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT, \
421 VK_IMAGE_USAGE_STORAGE_BIT); \
422 MAP_TO(VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT, \
423 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); \
424 MAP_TO(VK_FORMAT_FEATURE_2_VIDEO_DECODE_OUTPUT_BIT_KHR, \
425 VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR); \
426 MAP_TO(VK_FORMAT_FEATURE_2_VIDEO_DECODE_DPB_BIT_KHR, \
427 VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR); \
428 MAP_TO(VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR, \
429 VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR); \
430 MAP_TO(VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR, \
431 VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR); \
435 #define MAP_TO(flag1, flag2) if (src & flag2) dst |= flag1;
436 FN_MAP_TO(VkFormatFeatureFlagBits2, feats, VkImageUsageFlags,
usage)
438 #define MAP_TO(flag1, flag2) if (src & flag1) dst |= flag2;
439 FN_MAP_TO(VkImageUsageFlags,
usage, VkFormatFeatureFlagBits2, feats)
444 VkImageTiling tiling,
447 VkImageAspectFlags *
aspect,
448 VkImageUsageFlags *supported_usage,
449 int disable_multiplane,
int need_storage)
455 const VkFormatFeatureFlagBits2 basic_flags = VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
456 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
457 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
461 VkFormatProperties3 fprops = {
462 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3,
464 VkFormatProperties2 prop = {
465 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
468 VkFormatFeatureFlagBits2 feats_primary, feats_secondary;
469 int basics_primary = 0, basics_secondary = 0;
470 int storage_primary = 0, storage_secondary = 0;
472 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
476 feats_primary = tiling == VK_IMAGE_TILING_LINEAR ?
477 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
478 basics_primary = (feats_primary & basic_flags) == basic_flags;
479 storage_primary = !!(feats_primary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
482 vk->GetPhysicalDeviceFormatProperties2(hwctx->
phys_dev,
485 feats_secondary = tiling == VK_IMAGE_TILING_LINEAR ?
486 fprops.linearTilingFeatures : fprops.optimalTilingFeatures;
487 basics_secondary = (feats_secondary & basic_flags) == basic_flags;
488 storage_secondary = !!(feats_secondary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
490 basics_secondary = basics_primary;
491 storage_secondary = storage_primary;
494 if (basics_primary &&
496 (!need_storage || (need_storage && (storage_primary | storage_secondary)))) {
510 *supported_usage = map_feats_to_usage(feats_primary) |
511 ((need_storage && (storage_primary | storage_secondary)) ?
512 VK_IMAGE_USAGE_STORAGE_BIT : 0);
514 }
else if (basics_secondary &&
515 (!need_storage || (need_storage && storage_secondary))) {
525 *supported_usage = map_feats_to_usage(feats_secondary);
541 static const char *lib_names[] = {
544 #elif defined(__APPLE__)
555 p->
libvulkan = dlopen(lib_names[
i], RTLD_NOW | RTLD_LOCAL);
598 { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_MEMORY },
599 { VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_SEM },
613 static VkBool32 VKAPI_CALL
vk_dbg_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
614 VkDebugUtilsMessageTypeFlagsEXT messageType,
615 const VkDebugUtilsMessengerCallbackDataEXT *
data,
622 switch (
data->messageIdNumber) {
633 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: l =
AV_LOG_VERBOSE;
break;
634 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: l =
AV_LOG_INFO;
break;
635 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: l =
AV_LOG_WARNING;
break;
636 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: l =
AV_LOG_ERROR;
break;
641 for (
int i = 0;
i <
data->cmdBufLabelCount;
i++)
647 #define ADD_VAL_TO_LIST(list, count, val) \
649 list = av_realloc_array(list, sizeof(*list), ++count); \
651 err = AVERROR(ENOMEM); \
654 list[count - 1] = av_strdup(val); \
655 if (!list[count - 1]) { \
656 err = AVERROR(ENOMEM); \
661 #define RELEASE_PROPS(props, count) \
663 for (int i = 0; i < count; i++) \
664 av_free((void *)((props)[i])); \
665 av_free((void *)props); \
683 const char *
const **
dst, uint32_t *num,
687 const char **extension_names =
NULL;
691 int err = 0, found, extensions_found = 0;
694 int optional_exts_num;
695 uint32_t sup_ext_count;
696 char *user_exts_str =
NULL;
698 VkExtensionProperties *sup_ext;
708 if (!user_exts_str) {
713 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count,
NULL);
714 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
717 vk->EnumerateInstanceExtensionProperties(
NULL, &sup_ext_count, sup_ext);
725 if (!user_exts_str) {
730 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
731 &sup_ext_count,
NULL);
732 sup_ext =
av_malloc_array(sup_ext_count,
sizeof(VkExtensionProperties));
735 vk->EnumerateDeviceExtensionProperties(hwctx->
phys_dev,
NULL,
736 &sup_ext_count, sup_ext);
739 for (
int i = 0;
i < optional_exts_num;
i++) {
740 tstr = optional_exts[
i].
name;
747 !strcmp(tstr, VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME)) {
751 for (
int j = 0; j < sup_ext_count; j++) {
752 if (!strcmp(tstr, sup_ext[j].extensionName)) {
769 tstr = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
771 for (
int j = 0; j < sup_ext_count; j++) {
772 if (!strcmp(tstr, sup_ext[j].extensionName)) {
788 #ifdef VK_KHR_shader_relaxed_extended_instruction
791 tstr = VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME;
793 for (
int j = 0; j < sup_ext_count; j++) {
794 if (!strcmp(tstr, sup_ext[j].extensionName)) {
812 char *save, *token =
av_strtok(user_exts_str,
"+", &save);
815 for (
int j = 0; j < sup_ext_count; j++) {
816 if (!strcmp(token, sup_ext[j].extensionName)) {
832 *
dst = extension_names;
833 *num = extensions_found;
847 const char *
const **
dst, uint32_t *num,
854 static const char layer_standard_validation[] = {
"VK_LAYER_KHRONOS_validation" };
855 int layer_standard_validation_found = 0;
857 uint32_t sup_layer_count;
858 VkLayerProperties *sup_layers;
861 char *user_layers_str =
NULL;
864 const char **enabled_layers =
NULL;
865 uint32_t enabled_layers_count = 0;
873 vk->EnumerateInstanceLayerProperties(&sup_layer_count,
NULL);
874 sup_layers =
av_malloc_array(sup_layer_count,
sizeof(VkLayerProperties));
877 vk->EnumerateInstanceLayerProperties(&sup_layer_count, sup_layers);
880 for (
int i = 0;
i < sup_layer_count;
i++)
884 if (!debug_opt && !user_layers)
889 if (!strcmp(debug_opt->
value,
"profile")) {
891 }
else if (!strcmp(debug_opt->
value,
"printf")) {
893 }
else if (!strcmp(debug_opt->
value,
"validate")) {
895 }
else if (!strcmp(debug_opt->
value,
"practices")) {
898 char *end_ptr =
NULL;
899 int idx = strtol(debug_opt->
value, &end_ptr, 10);
900 if (end_ptr == debug_opt->
value || end_ptr[0] !=
'\0' ||
915 for (
int i = 0;
i < sup_layer_count;
i++) {
916 if (!strcmp(layer_standard_validation, sup_layers[
i].layerName)) {
918 layer_standard_validation);
919 ADD_VAL_TO_LIST(enabled_layers, enabled_layers_count, layer_standard_validation);
921 layer_standard_validation_found = 1;
925 if (!layer_standard_validation_found) {
927 "Validation Layer \"%s\" not supported\n", layer_standard_validation);
940 if (!user_layers_str) {
945 token =
av_strtok(user_layers_str,
"+", &save);
950 if (!strcmp(layer_standard_validation, token) && layer_standard_validation_found) {
956 for (
int j = 0; j < sup_layer_count; j++) {
957 if (!strcmp(token, sup_layers[j].layerName)) {
968 if (!strcmp(layer_standard_validation, token))
972 "Layer \"%s\" not supported\n", token);
989 *
dst = enabled_layers;
990 *num = enabled_layers_count;
1005 VkApplicationInfo application_info = {
1006 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
1007 .pApplicationName =
"ffmpeg",
1011 .pEngineName =
"libavutil",
1012 .apiVersion = VK_API_VERSION_1_3,
1017 VkValidationFeaturesEXT validation_features = {
1018 .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
1020 VkInstanceCreateInfo inst_props = {
1021 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
1022 .pApplicationInfo = &application_info,
1038 &inst_props.enabledLayerCount, debug_mode);
1044 &inst_props.enabledExtensionCount, *debug_mode);
1052 static const VkValidationFeatureEnableEXT feat_list_validate[] = {
1053 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1054 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1055 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
1057 validation_features.pEnabledValidationFeatures = feat_list_validate;
1058 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_validate);
1059 inst_props.pNext = &validation_features;
1061 static const VkValidationFeatureEnableEXT feat_list_debug[] = {
1062 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1063 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1064 VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT,
1066 validation_features.pEnabledValidationFeatures = feat_list_debug;
1067 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_debug);
1068 inst_props.pNext = &validation_features;
1070 static const VkValidationFeatureEnableEXT feat_list_practices[] = {
1071 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1072 VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT,
1074 validation_features.pEnabledValidationFeatures = feat_list_practices;
1075 validation_features.enabledValidationFeatureCount =
FF_ARRAY_ELEMS(feat_list_practices);
1076 inst_props.pNext = &validation_features;
1080 for (
int i = 0;
i < inst_props.enabledExtensionCount;
i++) {
1081 if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
1082 inst_props.ppEnabledExtensionNames[
i])) {
1083 inst_props.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
1090 ret = vk->CreateInstance(&inst_props, hwctx->
alloc, &hwctx->
inst);
1093 if (
ret != VK_SUCCESS) {
1110 VkDebugUtilsMessengerCreateInfoEXT dbg = {
1111 .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
1112 .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
1113 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
1114 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
1115 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
1116 .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
1117 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
1118 VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
1123 vk->CreateDebugUtilsMessengerEXT(hwctx->
inst, &dbg,
1130 RELEASE_PROPS(inst_props.ppEnabledLayerNames, inst_props.enabledLayerCount);
1149 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
return "integrated";
1150 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
return "discrete";
1151 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
return "virtual";
1152 case VK_PHYSICAL_DEVICE_TYPE_CPU:
return "software";
1153 default:
return "unknown";
1160 int err = 0, choice = -1;
1166 VkPhysicalDevice *devices =
NULL;
1167 VkPhysicalDeviceIDProperties *idp =
NULL;
1168 VkPhysicalDeviceProperties2 *prop =
NULL;
1169 VkPhysicalDeviceDrmPropertiesEXT *drm_prop =
NULL;
1171 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num,
NULL);
1172 if (
ret != VK_SUCCESS || !num) {
1181 ret = vk->EnumeratePhysicalDevices(hwctx->
inst, &num, devices);
1182 if (
ret != VK_SUCCESS) {
1202 drm_prop =
av_calloc(num,
sizeof(*drm_prop));
1210 for (
int i = 0;
i < num;
i++) {
1212 drm_prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT;
1213 idp[
i].pNext = &drm_prop[
i];
1215 idp[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
1216 prop[
i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1217 prop[
i].pNext = &idp[
i];
1219 vk->GetPhysicalDeviceProperties2(devices[
i], &prop[
i]);
1221 prop[
i].properties.deviceName,
1223 prop[
i].properties.deviceID);
1227 for (
int i = 0;
i < num;
i++) {
1228 if (!strncmp(idp[
i].deviceUUID, select->
uuid, VK_UUID_SIZE)) {
1237 for (
int i = 0;
i < num;
i++) {
1238 if ((select->
drm_major == drm_prop[
i].primaryMajor &&
1239 select->
drm_minor == drm_prop[
i].primaryMinor) ||
1240 (select->
drm_major == drm_prop[
i].renderMajor &&
1241 select->
drm_minor == drm_prop[
i].renderMinor)) {
1250 }
else if (select->
name) {
1252 for (
int i = 0;
i < num;
i++) {
1253 if (strstr(prop[
i].properties.deviceName, select->
name)) {
1264 for (
int i = 0;
i < num;
i++) {
1265 if (select->
pci_device == prop[
i].properties.deviceID) {
1276 for (
int i = 0;
i < num;
i++) {
1277 if (select->
vendor_id == prop[
i].properties.vendorID) {
1287 if (select->
index < num) {
1288 choice = select->
index;
1300 choice, prop[choice].properties.deviceName,
1302 prop[choice].properties.deviceID);
1316 VkQueueFlagBits
flags)
1319 uint32_t min_score = UINT32_MAX;
1321 for (
int i = 0;
i < num_qf;
i++) {
1322 VkQueueFlagBits qflags = qf[
i].queueFamilyProperties.queueFlags;
1325 if ((
flags & VK_QUEUE_TRANSFER_BIT) &&
1326 (qflags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)))
1327 qflags |= VK_QUEUE_TRANSFER_BIT;
1329 if (qflags &
flags) {
1330 uint32_t score =
av_popcount(qflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1331 if (score < min_score) {
1339 qf[
index].queueFamilyProperties.timestampValidBits++;
1345 VkQueueFamilyVideoPropertiesKHR *qf_vid, uint32_t num_qf,
1346 VkVideoCodecOperationFlagBitsKHR
flags)
1349 uint32_t min_score = UINT32_MAX;
1351 for (
int i = 0;
i < num_qf;
i++) {
1352 const VkQueueFlagBits qflags = qf[
i].queueFamilyProperties.queueFlags;
1353 const VkQueueFlagBits vflags = qf_vid[
i].videoCodecOperations;
1355 if (!(qflags & (VK_QUEUE_VIDEO_ENCODE_BIT_KHR | VK_QUEUE_VIDEO_DECODE_BIT_KHR)))
1358 if (vflags &
flags) {
1359 uint32_t score =
av_popcount(vflags) + qf[
i].queueFamilyProperties.timestampValidBits;
1360 if (score < min_score) {
1368 qf[
index].queueFamilyProperties.timestampValidBits++;
1380 VkQueueFamilyProperties2 *qf =
NULL;
1381 VkQueueFamilyVideoPropertiesKHR *qf_vid =
NULL;
1384 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &num,
NULL);
1395 qf_vid =
av_malloc_array(num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
1399 for (uint32_t
i = 0;
i < num;
i++) {
1400 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1401 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1403 qf[
i] = (VkQueueFamilyProperties2) {
1404 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
1405 .pNext = &qf_vid[
i],
1410 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &num, qf);
1413 for (
int i = 0;
i < num;
i++) {
1415 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_GRAPHICS_BIT) ?
" graphics" :
"",
1416 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_COMPUTE_BIT) ?
" compute" :
"",
1417 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_TRANSFER_BIT) ?
" transfer" :
"",
1418 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ?
" encode" :
"",
1419 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_VIDEO_DECODE_BIT_KHR) ?
" decode" :
"",
1420 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_SPARSE_BINDING_BIT) ?
" sparse" :
"",
1421 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_OPTICAL_FLOW_BIT_NV) ?
" optical_flow" :
"",
1422 ((qf[
i].queueFamilyProperties.queueFlags) & VK_QUEUE_PROTECTED_BIT) ?
" protected" :
"",
1423 qf[
i].queueFamilyProperties.queueCount);
1427 qf[
i].queueFamilyProperties.timestampValidBits = 0;
1433 #define PICK_QF(type, vid_op) \
1439 idx = pick_video_queue_family(qf, qf_vid, num, vid_op); \
1441 idx = pick_queue_family(qf, num, type); \
1446 for (i = 0; i < hwctx->nb_qf; i++) { \
1447 if (hwctx->qf[i].idx == idx) { \
1448 hwctx->qf[i].flags |= type; \
1449 hwctx->qf[i].video_caps |= vid_op; \
1453 if (i == hwctx->nb_qf) { \
1454 hwctx->qf[i].idx = idx; \
1455 hwctx->qf[i].num = qf[idx].queueFamilyProperties.queueCount; \
1456 hwctx->qf[i].flags = type; \
1457 hwctx->qf[i].video_caps = vid_op; \
1462 PICK_QF(VK_QUEUE_GRAPHICS_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1463 PICK_QF(VK_QUEUE_COMPUTE_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1464 PICK_QF(VK_QUEUE_TRANSFER_BIT, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1465 PICK_QF(VK_QUEUE_OPTICAL_FLOW_BIT_NV, VK_VIDEO_CODEC_OPERATION_NONE_KHR);
1467 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR);
1468 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR);
1470 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR);
1471 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR);
1473 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR);
1481 sizeof(VkDeviceQueueCreateInfo));
1482 if (!cd->pQueueCreateInfos)
1485 for (uint32_t
i = 0;
i < hwctx->
nb_qf;
i++) {
1488 VkDeviceQueueCreateInfo *pc;
1489 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++) {
1490 if (hwctx->
qf[
i].
idx == cd->pQueueCreateInfos[j].queueFamilyIndex) {
1500 for (uint32_t j = 0; j < cd->queueCreateInfoCount; j++)
1501 av_free((
void *)cd->pQueueCreateInfos[
i].pQueuePriorities);
1502 av_free((
void *)cd->pQueueCreateInfos);
1506 for (uint32_t j = 0; j < hwctx->
qf[
i].
num; j++)
1509 pc = (VkDeviceQueueCreateInfo *)cd->pQueueCreateInfos;
1510 pc[cd->queueCreateInfoCount++] = (VkDeviceQueueCreateInfo) {
1511 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1512 .queueFamilyIndex = hwctx->
qf[
i].
idx,
1513 .queueCount = hwctx->
qf[
i].
num,
1518 #if FF_API_VULKAN_FIXED_QUEUES
1527 #define SET_OLD_QF(field, nb_field, type) \
1529 if (field < 0 && hwctx->qf[i].flags & type) { \
1530 field = hwctx->qf[i].idx; \
1531 nb_field = hwctx->qf[i].num; \
1535 for (uint32_t
i = 0;
i < hwctx->
nb_qf;
i++) {
1565 vk->DestroyDebugUtilsMessengerEXT(hwctx->
inst, p->
debug_ctx,
1569 vk->DestroyInstance(hwctx->
inst, hwctx->
alloc);
1593 int disable_multiplane,
1604 VkDeviceCreateInfo dev_info = {
1605 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1618 &dev_info.enabledExtensionCount, debug_mode))) {
1619 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1620 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1621 av_free((
void *)dev_info.pQueueCreateInfos);
1627 vk->GetPhysicalDeviceFeatures2(hwctx->
phys_dev, &supported_feats.
device);
1633 dev_info.pEnabledFeatures = &p->
feats.
device.features;
1643 for (
int i = 0;
i < dev_info.queueCreateInfoCount;
i++)
1644 av_free((
void *)dev_info.pQueueCreateInfos[
i].pQueuePriorities);
1645 av_free((
void *)dev_info.pQueueCreateInfos);
1647 if (
ret != VK_SUCCESS) {
1650 for (
int i = 0;
i < dev_info.enabledExtensionCount;
i++)
1651 av_free((
void *)dev_info.ppEnabledExtensionNames[
i]);
1652 av_free((
void *)dev_info.ppEnabledExtensionNames);
1703 VkQueueFamilyProperties2 *qf;
1704 VkQueueFamilyVideoPropertiesKHR *qf_vid;
1705 int graph_index, comp_index, tx_index, enc_index, dec_index;
1724 p->
props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1726 p->
hprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;
1728 vk->GetPhysicalDeviceProperties2(hwctx->
phys_dev, &p->
props);
1730 p->
props.properties.deviceName);
1733 p->
props.properties.limits.optimalBufferCopyRowPitchAlignment);
1735 p->
props.properties.limits.minMemoryMapAlignment);
1737 p->
props.properties.limits.nonCoherentAtomSize);
1740 p->
hprops.minImportedHostPointerAlignment);
1744 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->
phys_dev, &qf_num,
NULL);
1754 qf_vid =
av_malloc_array(qf_num,
sizeof(VkQueueFamilyVideoPropertiesKHR));
1760 for (uint32_t
i = 0;
i < qf_num;
i++) {
1761 qf_vid[
i] = (VkQueueFamilyVideoPropertiesKHR) {
1762 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,
1764 qf[
i] = (VkQueueFamilyProperties2) {
1765 .sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
1766 .pNext = &qf_vid[
i],
1770 vk->GetPhysicalDeviceQueueFamilyProperties2(hwctx->
phys_dev, &qf_num, qf);
1779 for (uint32_t
i = 0;
i < qf_num;
i++) {
1786 for (uint32_t j = 0; j < qf[
i].queueFamilyProperties.queueCount; j++) {
1797 #if FF_API_VULKAN_FIXED_QUEUES
1805 #define CHECK_QUEUE(type, required, fidx, ctx_qf, qc) \
1807 if (ctx_qf < 0 && required) { \
1808 av_log(ctx, AV_LOG_ERROR, "%s queue family is required, but marked as missing" \
1809 " in the context!\n", type); \
1810 err = AVERROR(EINVAL); \
1812 } else if (fidx < 0 || ctx_qf < 0) { \
1814 } else if (ctx_qf >= qf_num) { \
1815 av_log(ctx, AV_LOG_ERROR, "Invalid %s family index %i (device has %i families)!\n", \
1816 type, ctx_qf, qf_num); \
1817 err = AVERROR(EINVAL); \
1821 av_log(ctx, AV_LOG_VERBOSE, "Using queue family %i (queues: %i)" \
1822 " for%s%s%s%s%s\n", \
1824 ctx_qf == graph_index ? " graphics" : "", \
1825 ctx_qf == comp_index ? " compute" : "", \
1826 ctx_qf == tx_index ? " transfers" : "", \
1827 ctx_qf == enc_index ? " encode" : "", \
1828 ctx_qf == dec_index ? " decode" : ""); \
1829 graph_index = (ctx_qf == graph_index) ? -1 : graph_index; \
1830 comp_index = (ctx_qf == comp_index) ? -1 : comp_index; \
1831 tx_index = (ctx_qf == tx_index) ? -1 : tx_index; \
1832 enc_index = (ctx_qf == enc_index) ? -1 : enc_index; \
1833 dec_index = (ctx_qf == dec_index) ? -1 : dec_index; \
1846 if (!hwctx->
nb_qf) {
1847 #define ADD_QUEUE(ctx_qf, qc, flag) \
1849 if (ctx_qf != -1) { \
1850 hwctx->qf[hwctx->nb_qf++] = (AVVulkanDeviceQueueFamily) { \
1868 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
1870 hwctx->
qf[
i].
flags & (VK_QUEUE_VIDEO_DECODE_BIT_KHR |
1871 VK_QUEUE_VIDEO_ENCODE_BIT_KHR)) {
1878 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
1882 for (
int j = (
i - 1); j >= 0; j--) {
1898 vk->GetPhysicalDeviceMemoryProperties(hwctx->
phys_dev, &p->
mprops);
1917 if (device && device[0]) {
1919 dev_select.
index = strtol(device, &end, 10);
1920 if (end == device) {
1921 dev_select.
index = 0;
1922 dev_select.
name = device;
1938 switch(src_ctx->
type) {
1942 VADisplay dpy = src_hwctx->
display;
1943 #if VA_CHECK_VERSION(1, 15, 0)
1945 VADisplayAttribute attr = {
1946 .type = VADisplayPCIID,
1951 #if VA_CHECK_VERSION(1, 15, 0)
1952 vas = vaGetDisplayAttributes(dpy, &attr, 1);
1953 if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED)
1954 dev_select.pci_device = (attr.value & 0xFFFF);
1957 if (!dev_select.pci_device) {
1958 vendor = vaQueryVendorString(dpy);
1964 if (strstr(vendor,
"AMD"))
1965 dev_select.vendor_id = 0x1002;
1974 struct stat drm_node_info;
1975 drmDevice *drm_dev_info;
1978 err = fstat(src_hwctx->
fd, &drm_node_info);
1985 dev_select.drm_major = major(drm_node_info.st_dev);
1986 dev_select.drm_minor = minor(drm_node_info.st_dev);
1987 dev_select.has_drm = 1;
1989 err = drmGetDevice(src_hwctx->
fd, &drm_dev_info);
1996 if (drm_dev_info->bustype == DRM_BUS_PCI)
1997 dev_select.pci_device = drm_dev_info->deviceinfo.pci->device_id;
1999 drmFreeDevice(&drm_dev_info);
2009 CudaFunctions *cu = cu_internal->
cuda_dl;
2011 int ret =
CHECK_CU(cu->cuDeviceGetUuid((CUuuid *)&dev_select.uuid,
2018 dev_select.has_uuid = 1;
2033 const void *hwconfig,
2042 VK_IMAGE_TILING_OPTIMAL,
2055 VK_IMAGE_TILING_OPTIMAL,
2065 constraints->
max_width = p->
props.properties.limits.maxImageDimension2D;
2066 constraints->
max_height = p->
props.properties.limits.maxImageDimension2D;
2079 VkMemoryPropertyFlagBits req_flags,
const void *alloc_extension,
2080 VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
2087 VkMemoryAllocateInfo alloc_info = {
2088 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2089 .pNext = alloc_extension,
2090 .allocationSize = req->size,
2095 for (
int i = 0;
i < p->
mprops.memoryTypeCount;
i++) {
2096 const VkMemoryType *
type = &p->
mprops.memoryTypes[
i];
2099 if (!(req->memoryTypeBits & (1 <<
i)))
2103 if ((
type->propertyFlags & req_flags) != req_flags)
2107 if (req->size > p->
mprops.memoryHeaps[
type->heapIndex].size)
2121 alloc_info.memoryTypeIndex =
index;
2123 ret = vk->AllocateMemory(dev_hwctx->
act_dev, &alloc_info,
2124 dev_hwctx->
alloc, mem);
2125 if (
ret != VK_SUCCESS) {
2131 *mem_flags |= p->
mprops.memoryTypes[
index].propertyFlags;
2141 if (internal->cuda_fc_ref) {
2147 CudaFunctions *cu = cu_internal->
cuda_dl;
2150 if (internal->cu_sem[
i])
2151 CHECK_CU(cu->cuDestroyExternalSemaphore(internal->cu_sem[
i]));
2152 if (internal->cu_mma[
i])
2153 CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[
i]));
2154 if (internal->ext_mem[
i])
2155 CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[
i]));
2157 if (internal->ext_sem_handle[
i])
2158 CloseHandle(internal->ext_sem_handle[
i]);
2159 if (internal->ext_mem_handle[
i])
2160 CloseHandle(internal->ext_mem_handle[
i]);
2185 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
2187 .pSemaphores =
f->sem,
2188 .pValues =
f->sem_value,
2189 .semaphoreCount = nb_sems,
2197 for (
int i = 0;
i < nb_images;
i++) {
2212 void *alloc_pnext,
size_t alloc_pnext_stride)
2214 int img_cnt = 0, err;
2222 while (
f->img[img_cnt]) {
2224 VkImageMemoryRequirementsInfo2 req_desc = {
2225 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
2226 .image =
f->img[img_cnt],
2228 VkMemoryDedicatedAllocateInfo ded_alloc = {
2229 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
2230 .pNext = (
void *)(((uint8_t *)alloc_pnext) + img_cnt*alloc_pnext_stride),
2232 VkMemoryDedicatedRequirements ded_req = {
2233 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
2235 VkMemoryRequirements2 req = {
2236 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
2240 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req);
2242 if (
f->tiling == VK_IMAGE_TILING_LINEAR)
2243 req.memoryRequirements.size =
FFALIGN(req.memoryRequirements.size,
2244 p->
props.properties.limits.minMemoryMapAlignment);
2247 use_ded_mem = ded_req.prefersDedicatedAllocation |
2248 ded_req.requiresDedicatedAllocation;
2250 ded_alloc.image =
f->img[img_cnt];
2254 f->tiling == VK_IMAGE_TILING_LINEAR ?
2255 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
2256 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2257 use_ded_mem ? &ded_alloc : (
void *)ded_alloc.pNext,
2258 &
f->flags, &
f->mem[img_cnt])))
2261 f->size[img_cnt] = req.memoryRequirements.size;
2262 bind_info[img_cnt].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
2263 bind_info[img_cnt].image =
f->img[img_cnt];
2264 bind_info[img_cnt].memory =
f->mem[img_cnt];
2270 ret = vk->BindImageMemory2(hwctx->
act_dev, img_cnt, bind_info);
2271 if (
ret != VK_SUCCESS) {
2299 uint32_t dst_qf = VK_QUEUE_FAMILY_IGNORED;
2300 VkImageLayout new_layout;
2301 VkAccessFlags2 new_access;
2302 VkPipelineStageFlagBits2 src_stage = VK_PIPELINE_STAGE_2_NONE;
2308 .
data = (uint8_t *)hwfc,
2312 .hw_frames_ctx = &tmp_ref,
2315 VkCommandBuffer cmd_buf;
2317 cmd_buf = exec->
buf;
2321 VK_PIPELINE_STAGE_2_NONE,
2322 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
2328 new_layout = VK_IMAGE_LAYOUT_GENERAL;
2329 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2332 new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
2333 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2336 new_layout = VK_IMAGE_LAYOUT_GENERAL;
2337 new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2340 new_layout = VK_IMAGE_LAYOUT_GENERAL;
2341 new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
2342 dst_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR;
2343 src_stage = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
2346 new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR;
2347 new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
2350 new_layout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR;
2351 new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2354 new_layout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR;
2355 new_access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2361 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
2362 new_access, new_layout, dst_qf);
2364 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
2365 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
2366 .pImageMemoryBarriers = img_bar,
2367 .imageMemoryBarrierCount = nb_img_bar,
2381 int frame_w,
int frame_h,
int plane)
2398 VkImageTiling tiling, VkImageUsageFlagBits
usage,
2399 VkImageCreateFlags
flags,
int nb_layers,
2410 VkExportSemaphoreCreateInfo ext_sem_info = {
2411 .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
2413 .handleTypes = IsWindows8OrGreater()
2414 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2415 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
2417 .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
2421 VkSemaphoreTypeCreateInfo sem_type_info = {
2422 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2428 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2432 VkSemaphoreCreateInfo sem_spawn = {
2433 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2434 .pNext = &sem_type_info,
2446 for (
int i = 0; (hwfc_vk->
format[
i] != VK_FORMAT_UNDEFINED);
i++) {
2447 VkImageCreateInfo create_info = {
2448 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2449 .pNext = create_pnext,
2450 .imageType = VK_IMAGE_TYPE_2D,
2454 .arrayLayers = nb_layers,
2457 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2459 .samples = VK_SAMPLE_COUNT_1_BIT,
2460 .pQueueFamilyIndices = p->
img_qfs,
2462 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2463 VK_SHARING_MODE_EXCLUSIVE,
2466 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
2469 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
2471 if (
ret != VK_SUCCESS) {
2479 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
2481 if (
ret != VK_SUCCESS) {
2489 f->layout[
i] = create_info.initialLayout;
2491 f->sem_value[
i] = 0;
2507 VkExternalMemoryHandleTypeFlags *comp_handle_types,
2508 VkExternalMemoryHandleTypeFlagBits *iexp,
2509 VkExternalMemoryHandleTypeFlagBits
exp)
2517 const VkImageDrmFormatModifierListCreateInfoEXT *drm_mod_info =
2519 VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
2520 int has_mods = hwctx->
tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && drm_mod_info;
2523 VkExternalImageFormatProperties eprops = {
2524 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
2526 VkImageFormatProperties2 props = {
2527 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
2530 VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
2531 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
2533 .pQueueFamilyIndices = p->
img_qfs,
2535 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2536 VK_SHARING_MODE_EXCLUSIVE,
2538 VkPhysicalDeviceExternalImageFormatInfo enext = {
2539 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
2541 .pNext = has_mods ? &phy_dev_mod_info :
NULL,
2543 VkPhysicalDeviceImageFormatInfo2 pinfo = {
2544 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
2545 .pNext = !
exp ?
NULL : &enext,
2547 .type = VK_IMAGE_TYPE_2D,
2549 .usage = hwctx->
usage,
2550 .flags = VK_IMAGE_CREATE_ALIAS_BIT,
2553 nb_mods = has_mods ? drm_mod_info->drmFormatModifierCount : 1;
2554 for (
int i = 0;
i < nb_mods;
i++) {
2556 phy_dev_mod_info.drmFormatModifier = drm_mod_info->pDrmFormatModifiers[
i];
2558 ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->
phys_dev,
2561 if (
ret == VK_SUCCESS) {
2563 *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes;
2577 VkExternalMemoryHandleTypeFlags e = 0x0;
2580 VkExternalMemoryImageCreateInfo eiinfo = {
2581 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
2588 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
2589 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
2593 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
2597 eminfo[
i].sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
2599 eminfo[
i].handleTypes = e;
2612 if ( (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2613 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR))
2615 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)
2617 else if (hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR)
2619 else if (hwctx->
usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)
2673 VkImageUsageFlagBits supported_usage;
2684 (hwctx->
tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
2685 hwctx->
tiling = VK_IMAGE_TILING_LINEAR;
2695 if (hwctx->
format[0] != VK_FORMAT_UNDEFINED) {
2700 "for the current sw_format %s!\n",
2712 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
2721 NULL, &supported_usage,
2724 (hwctx->
usage & VK_IMAGE_USAGE_STORAGE_BIT));
2730 if (!hwctx->
usage) {
2731 hwctx->
usage = supported_usage & (VK_BUFFER_USAGE_TRANSFER_DST_BIT |
2732 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
2733 VK_IMAGE_USAGE_STORAGE_BIT |
2734 VK_IMAGE_USAGE_SAMPLED_BIT);
2737 if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
2740 hwctx->
usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
2747 int is_lone_dpb = ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR) ||
2748 ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
2749 !(hwctx->
usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)));
2750 int sampleable = hwctx->
usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
2751 VK_IMAGE_USAGE_STORAGE_BIT);
2752 hwctx->
img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
2753 if (sampleable && !is_lone_dpb) {
2754 hwctx->
img_flags |= VK_IMAGE_CREATE_ALIAS_BIT;
2756 hwctx->
img_flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
2764 if ((hwctx->
usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
2767 const VkVideoProfileListInfoKHR *pl;
2770 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
2773 for (
i = 0;
i < pl->profileCount;
i++) {
2775 if (pl->pProfiles[
i].videoCodecOperation & 0xFFFF0000)
2778 if (
i == pl->profileCount)
2779 hwctx->
img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
2870 static const struct {
2871 uint32_t drm_fourcc;
2873 } vulkan_drm_format_map[] = {
2874 { DRM_FORMAT_R8, VK_FORMAT_R8_UNORM },
2875 { DRM_FORMAT_R16, VK_FORMAT_R16_UNORM },
2876 { DRM_FORMAT_GR88, VK_FORMAT_R8G8_UNORM },
2877 { DRM_FORMAT_RG88, VK_FORMAT_R8G8_UNORM },
2878 { DRM_FORMAT_GR1616, VK_FORMAT_R16G16_UNORM },
2879 { DRM_FORMAT_RG1616, VK_FORMAT_R16G16_UNORM },
2880 { DRM_FORMAT_ARGB8888, VK_FORMAT_B8G8R8A8_UNORM },
2881 { DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM },
2882 { DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM },
2883 { DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM },
2884 { DRM_FORMAT_ARGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
2885 { DRM_FORMAT_ABGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
2886 { DRM_FORMAT_XRGB2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
2887 { DRM_FORMAT_XBGR2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
2890 #ifdef DRM_FORMAT_XYUV8888
2891 { DRM_FORMAT_XYUV8888, VK_FORMAT_R8G8B8A8_UNORM },
2892 { DRM_FORMAT_XVYU2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 } ,
2893 { DRM_FORMAT_XVYU12_16161616, VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 } ,
2894 { DRM_FORMAT_XVYU16161616, VK_FORMAT_R16G16B16A16_UNORM } ,
2898 static inline VkFormat drm_to_vulkan_fmt(uint32_t drm_fourcc)
2901 if (vulkan_drm_format_map[
i].drm_fourcc == drm_fourcc)
2902 return vulkan_drm_format_map[
i].vk_format;
2903 return VK_FORMAT_UNDEFINED;
2912 int bind_counts = 0;
2922 if (drm_to_vulkan_fmt(
desc->layers[
i].format) == VK_FORMAT_UNDEFINED) {
2924 desc->layers[
i].format);
2935 f->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
2937 for (
int i = 0;
i <
desc->nb_layers;
i++) {
2941 VkSemaphoreTypeCreateInfo sem_type_info = {
2942 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
2943 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
2946 VkSemaphoreCreateInfo sem_spawn = {
2947 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2948 .pNext = &sem_type_info,
2953 VkImageDrmFormatModifierExplicitCreateInfoEXT ext_img_mod_spec = {
2954 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
2955 .drmFormatModifier =
desc->objects[0].format_modifier,
2956 .drmFormatModifierPlaneCount =
planes,
2957 .pPlaneLayouts = (
const VkSubresourceLayout *)&ext_img_layouts,
2959 VkExternalMemoryImageCreateInfo ext_img_spec = {
2960 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
2961 .pNext = &ext_img_mod_spec,
2962 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
2964 VkImageCreateInfo create_info = {
2965 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2966 .pNext = &ext_img_spec,
2967 .imageType = VK_IMAGE_TYPE_2D,
2968 .format = drm_to_vulkan_fmt(
desc->layers[
i].format),
2973 .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
2974 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2976 .samples = VK_SAMPLE_COUNT_1_BIT,
2977 .pQueueFamilyIndices = p->
img_qfs,
2979 .sharingMode = p->
nb_img_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
2980 VK_SHARING_MODE_EXCLUSIVE,
2984 VkExternalImageFormatProperties ext_props = {
2985 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
2987 VkImageFormatProperties2 props_ret = {
2988 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
2989 .pNext = &ext_props,
2991 VkPhysicalDeviceImageDrmFormatModifierInfoEXT props_drm_mod = {
2992 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
2993 .drmFormatModifier = ext_img_mod_spec.drmFormatModifier,
2994 .pQueueFamilyIndices = create_info.pQueueFamilyIndices,
2995 .queueFamilyIndexCount = create_info.queueFamilyIndexCount,
2996 .sharingMode = create_info.sharingMode,
2998 VkPhysicalDeviceExternalImageFormatInfo props_ext = {
2999 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
3000 .pNext = &props_drm_mod,
3001 .handleType = ext_img_spec.handleTypes,
3003 VkPhysicalDeviceImageFormatInfo2 fmt_props;
3006 create_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT |
3007 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3009 create_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT |
3010 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3012 fmt_props = (VkPhysicalDeviceImageFormatInfo2) {
3013 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3014 .pNext = &props_ext,
3015 .format = create_info.format,
3016 .type = create_info.imageType,
3017 .tiling = create_info.tiling,
3018 .usage = create_info.usage,
3019 .flags = create_info.flags,
3023 ret = vk->GetPhysicalDeviceImageFormatProperties2(hwctx->
phys_dev,
3024 &fmt_props, &props_ret);
3025 if (
ret != VK_SUCCESS) {
3033 get_plane_wh(&create_info.extent.width, &create_info.extent.height,
3037 for (
int j = 0; j <
planes; j++) {
3038 ext_img_layouts[j].offset =
desc->layers[
i].planes[j].offset;
3039 ext_img_layouts[j].rowPitch =
desc->layers[
i].planes[j].pitch;
3040 ext_img_layouts[j].size = 0;
3041 ext_img_layouts[j].arrayPitch = 0;
3042 ext_img_layouts[j].depthPitch = 0;
3046 ret = vk->CreateImage(hwctx->
act_dev, &create_info,
3048 if (
ret != VK_SUCCESS) {
3055 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3057 if (
ret != VK_SUCCESS) {
3064 f->queue_family[
i] = VK_QUEUE_FAMILY_EXTERNAL;
3065 f->layout[
i] = create_info.initialLayout;
3067 f->sem_value[
i] = 0;
3070 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3072 VkImageMemoryRequirementsInfo2 req_desc = {
3073 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
3076 VkMemoryDedicatedRequirements ded_req = {
3077 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
3079 VkMemoryRequirements2 req2 = {
3080 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3085 VkMemoryFdPropertiesKHR fdmp = {
3086 .sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR,
3092 VkImportMemoryFdInfoKHR idesc = {
3093 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
3094 .fd = dup(
desc->objects[
desc->layers[
i].planes[0].object_index].fd),
3095 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3097 VkMemoryDedicatedAllocateInfo ded_alloc = {
3098 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
3100 .image = req_desc.image,
3104 ret = vk->GetMemoryFdPropertiesKHR(hwctx->
act_dev,
3105 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3107 if (
ret != VK_SUCCESS) {
3115 vk->GetImageMemoryRequirements2(hwctx->
act_dev, &req_desc, &req2);
3118 req2.memoryRequirements.memoryTypeBits = fdmp.memoryTypeBits;
3121 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
3122 (ded_req.prefersDedicatedAllocation ||
3123 ded_req.requiresDedicatedAllocation) ?
3124 &ded_alloc : ded_alloc.pNext,
3125 &
f->flags, &
f->mem[
i]);
3131 f->size[
i] = req2.memoryRequirements.size;
3134 for (
int i = 0;
i <
desc->nb_layers;
i++) {
3136 for (
int j = 0; j <
planes; j++) {
3137 VkImageAspectFlagBits aspect = j == 0 ? VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT :
3138 j == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT :
3139 VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
3141 plane_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO;
3143 plane_info[bind_counts].planeAspect = aspect;
3145 bind_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
3147 bind_info[bind_counts].image =
f->img[
i];
3148 bind_info[bind_counts].memory =
f->mem[
i];
3151 bind_info[bind_counts].memoryOffset = 0;
3158 ret = vk->BindImageMemory2(hwctx->
act_dev, bind_counts, bind_info);
3159 if (
ret != VK_SUCCESS) {
3189 #ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
3191 VkCommandBuffer cmd_buf;
3197 for (
int i = 0;
i <
desc->nb_objects;
i++) {
3198 VkSemaphoreTypeCreateInfo sem_type_info = {
3199 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
3200 .semaphoreType = VK_SEMAPHORE_TYPE_BINARY,
3202 VkSemaphoreCreateInfo sem_spawn = {
3203 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3204 .pNext = &sem_type_info,
3206 VkImportSemaphoreFdInfoKHR import_info;
3207 struct dma_buf_export_sync_file implicit_fd_info = {
3208 .flags = DMA_BUF_SYNC_READ,
3212 if (ioctl(
desc->objects[
i].fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE,
3213 &implicit_fd_info)) {
3218 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3222 ret = vk->CreateSemaphore(hwctx->
act_dev, &sem_spawn,
3223 hwctx->
alloc, &drm_sync_sem[
i]);
3224 if (
ret != VK_SUCCESS) {
3229 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3233 import_info = (VkImportSemaphoreFdInfoKHR) {
3234 .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
3235 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
3236 .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
3237 .semaphore = drm_sync_sem[
i],
3238 .fd = implicit_fd_info.fd,
3241 ret = vk->ImportSemaphoreFdKHR(hwctx->
act_dev, &import_info);
3242 if (
ret != VK_SUCCESS) {
3247 vk->DestroySemaphore(hwctx->
act_dev, drm_sync_sem[
i], hwctx->
alloc);
3253 cmd_buf = exec->
buf;
3259 drm_sync_sem,
desc->nb_objects,
3260 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 1);
3265 VK_PIPELINE_STAGE_2_NONE,
3266 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
3271 VK_PIPELINE_STAGE_2_NONE,
3272 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
3274 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT : 0x0) |
3276 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT : 0x0),
3277 VK_IMAGE_LAYOUT_GENERAL,
3278 VK_QUEUE_FAMILY_IGNORED);
3280 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
3281 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
3282 .pImageMemoryBarriers = img_bar,
3283 .imageMemoryBarrierCount = nb_img_bar,
3294 "image may be corrupted.\n");
3309 if ((err = vulkan_map_from_drm_frame_desc(hwfc, &
f,
src,
flags)))
3313 dst->data[0] = (uint8_t *)
f;
3315 dst->height =
src->height;
3318 &vulkan_unmap_from_drm,
f);
3322 err = vulkan_map_from_drm_frame_sync(hwfc,
dst,
src,
flags);
3345 VASurfaceID surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
3351 vaSyncSurface(vaapi_ctx->display, surface_id);
3359 err = vulkan_map_from_drm(dst_fc,
dst,
tmp,
flags);
3392 CudaFunctions *cu = cu_internal->
cuda_dl;
3393 CUarray_format cufmt =
desc->comp[0].depth > 8 ? CU_AD_FORMAT_UNSIGNED_INT16 :
3394 CU_AD_FORMAT_UNSIGNED_INT8;
3399 if (!dst_int->cuda_fc_ref) {
3401 if (!dst_int->cuda_fc_ref)
3405 CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = {
3410 .NumChannels = 1 + ((
planes == 2) &&
i),
3418 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3419 .type = IsWindows8OrGreater()
3420 ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
3421 : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT,
3422 .size = dst_f->
size[
i],
3424 VkMemoryGetWin32HandleInfoKHR export_info = {
3425 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
3426 .memory = dst_f->
mem[
i],
3427 .handleType = IsWindows8OrGreater()
3428 ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
3429 : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
3431 VkSemaphoreGetWin32HandleInfoKHR sem_export = {
3432 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
3433 .semaphore = dst_f->
sem[
i],
3434 .handleType = IsWindows8OrGreater()
3435 ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
3436 : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
3438 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3442 ret = vk->GetMemoryWin32HandleKHR(hwctx->
act_dev, &export_info,
3443 &ext_desc.handle.win32.handle);
3444 if (
ret != VK_SUCCESS) {
3450 dst_int->ext_mem_handle[
i] = ext_desc.handle.win32.handle;
3452 CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
3453 .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
3454 .size = dst_f->
size[
i],
3456 VkMemoryGetFdInfoKHR export_info = {
3457 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
3458 .memory = dst_f->
mem[
i],
3459 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
3461 VkSemaphoreGetFdInfoKHR sem_export = {
3462 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
3463 .semaphore = dst_f->
sem[
i],
3464 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
3466 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
3470 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
3471 &ext_desc.handle.fd);
3472 if (
ret != VK_SUCCESS) {
3480 ret =
CHECK_CU(cu->cuImportExternalMemory(&dst_int->ext_mem[
i], &ext_desc));
3483 close(ext_desc.handle.fd);
3490 tex_desc.arrayDesc.Width = p_w;
3491 tex_desc.arrayDesc.Height = p_h;
3493 ret =
CHECK_CU(cu->cuExternalMemoryGetMappedMipmappedArray(&dst_int->cu_mma[
i],
3494 dst_int->ext_mem[
i],
3501 ret =
CHECK_CU(cu->cuMipmappedArrayGetLevel(&dst_int->cu_array[
i],
3502 dst_int->cu_mma[
i], 0));
3509 ret = vk->GetSemaphoreWin32HandleKHR(hwctx->
act_dev, &sem_export,
3510 &ext_sem_desc.handle.win32.handle);
3512 ret = vk->GetSemaphoreFdKHR(hwctx->
act_dev, &sem_export,
3513 &ext_sem_desc.handle.fd);
3515 if (
ret != VK_SUCCESS) {
3522 dst_int->ext_sem_handle[
i] = ext_sem_desc.handle.win32.handle;
3525 ret =
CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[
i],
3529 close(ext_sem_desc.handle.fd);
3559 CudaFunctions *cu = cu_internal->
cuda_dl;
3569 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
3573 err = vulkan_export_to_cuda(hwfc,
src->hw_frames_ctx,
dst);
3582 s_w_par[
i].params.fence.value = dst_f->
sem_value[
i] + 0;
3583 s_s_par[
i].params.fence.value = dst_f->
sem_value[
i] + 1;
3586 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
3587 planes, cuda_dev->stream));
3592 CUDA_MEMCPY2D cpy = {
3593 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
3594 .srcDevice = (CUdeviceptr)
src->data[
i],
3595 .srcPitch =
src->linesize[
i],
3598 .dstMemoryType = CU_MEMORYTYPE_ARRAY,
3599 .dstArray = dst_int->cu_array[
i],
3605 cpy.WidthInBytes = p_w *
desc->comp[
i].step;
3608 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
3613 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
3614 planes, cuda_dev->stream));
3640 switch (
src->format) {
3645 return vulkan_map_from_vaapi(hwfc,
dst,
src,
flags);
3651 return vulkan_map_from_drm(hwfc,
dst,
src,
flags);
3661 typedef struct VulkanDRMMapping {
3676 static inline uint32_t vulkan_fmt_to_drm(
VkFormat vkfmt)
3679 if (vulkan_drm_format_map[
i].vk_format == vkfmt)
3680 return vulkan_drm_format_map[
i].drm_fourcc;
3681 return DRM_FORMAT_INVALID;
3696 VkImageDrmFormatModifierPropertiesEXT drm_mod = {
3697 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
3699 VkSemaphoreWaitInfo wait_info = {
3700 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
3702 .semaphoreCount =
planes,
3714 wait_info.pSemaphores =
f->sem;
3715 wait_info.pValues =
f->sem_value;
3717 vk->WaitSemaphores(hwctx->
act_dev, &wait_info, UINT64_MAX);
3723 ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->
act_dev,
f->img[0],
3725 if (
ret != VK_SUCCESS) {
3731 for (
int i = 0; (
i <
planes) && (
f->mem[
i]);
i++) {
3732 VkMemoryGetFdInfoKHR export_info = {
3733 .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
3734 .memory =
f->mem[
i],
3735 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
3738 ret = vk->GetMemoryFdKHR(hwctx->
act_dev, &export_info,
3740 if (
ret != VK_SUCCESS) {
3753 VkSubresourceLayout
layout;
3754 VkImageSubresource sub = {
3755 .aspectMask = VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT,
3759 drm_desc->
layers[
i].
format = vulkan_fmt_to_drm(plane_vkfmt);
3770 if (
f->tiling == VK_IMAGE_TILING_OPTIMAL)
3773 vk->GetImageSubresourceLayout(hwctx->
act_dev,
f->img[
i], &sub, &
layout);
3782 dst->height =
src->height;
3783 dst->data[0] = (uint8_t *)drm_desc;
3827 switch (
dst->format) {
3837 return vulkan_map_to_vaapi(hwfc,
dst,
src,
flags);
3849 AVFrame *swf, VkBufferImageCopy *region,
3859 const VkMappedMemoryRange flush_info = {
3860 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
3861 .memory = vkbuf->
mem,
3862 .size = VK_WHOLE_SIZE,
3865 if (!(vkbuf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) && !upload) {
3866 ret = vk->InvalidateMappedMemoryRanges(hwctx->
act_dev, 1,
3868 if (
ret != VK_SUCCESS) {
3877 region[
i].bufferRowLength,
3881 region[
i].imageExtent.height);
3883 if (!(vkbuf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) && upload) {
3884 ret = vk->FlushMappedMemoryRanges(hwctx->
act_dev, 1,
3886 if (
ret != VK_SUCCESS) {
3897 AVFrame *swf, VkBufferImageCopy *region,
int upload)
3904 size_t buf_offset = 0;
3913 p->
props.properties.limits.optimalBufferCopyRowPitchAlignment);
3914 size = p_h*linesize;
3916 region[
i] = (VkBufferImageCopy) {
3917 .bufferOffset = buf_offset,
3918 .bufferRowLength = linesize,
3919 .bufferImageHeight = p_h,
3920 .imageSubresource.layerCount = 1,
3921 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
3926 p->
props.properties.limits.optimalBufferCopyOffsetAlignment);
3930 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
3931 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
3933 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
3934 VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
3944 VkExternalMemoryBufferCreateInfo *create_desc,
3945 VkImportMemoryHostPointerInfoEXT *import_desc,
3946 VkMemoryHostPointerPropertiesEXT props)
3954 VkBufferCreateInfo buf_spawn = {
3955 .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
3956 .pNext = create_desc,
3958 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
3961 VkMemoryRequirements req = {
3963 .alignment = p->
hprops.minImportedHostPointerAlignment,
3964 .memoryTypeBits = props.memoryTypeBits,
3968 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
3969 import_desc, &vkb->
flags, &vkb->
mem);
3974 if (
ret != VK_SUCCESS) {
3980 if (
ret != VK_SUCCESS) {
3998 AVFrame *swf, VkBufferImageCopy *region,
int upload)
4008 VkExternalMemoryBufferCreateInfo create_desc = {
4009 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
4010 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
4012 VkImportMemoryHostPointerInfoEXT import_desc = {
4013 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
4014 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
4016 VkMemoryHostPointerPropertiesEXT props;
4033 offs = (uintptr_t)swf->
data[
i] % p->
hprops.minImportedHostPointerAlignment;
4034 import_desc.pHostPointer = swf->
data[
i] - offs;
4036 props = (VkMemoryHostPointerPropertiesEXT) {
4037 VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT,
4039 ret = vk->GetMemoryHostPointerPropertiesEXT(hwctx->
act_dev,
4040 import_desc.handleType,
4041 import_desc.pHostPointer,
4043 if (!(
ret == VK_SUCCESS && props.memoryTypeBits)) {
4049 region[
i] = (VkBufferImageCopy) {
4050 .bufferOffset = offs,
4052 .bufferImageHeight = p_h,
4053 .imageSubresource.layerCount = 1,
4054 .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
4059 buffer_size = offs + swf->
linesize[
i]*p_h;
4060 buffer_size =
FFALIGN(buffer_size, p->
props.properties.limits.minMemoryMapAlignment);
4061 buffer_size =
FFALIGN(buffer_size, p->
hprops.minImportedHostPointerAlignment);
4071 upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
4072 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
4073 buffer_size, &create_desc, &import_desc,
4083 if (!
dst[*nb_bufs]) {
4095 for (
int i = 0;
i < (*nb_bufs);
i++)
4109 int host_mapped = 0;
4124 VkCommandBuffer cmd_buf;
4157 cmd_buf = exec->
buf;
4163 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
4164 VK_PIPELINE_STAGE_2_TRANSFER_BIT);
4188 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
4189 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,
4190 upload ? VK_ACCESS_TRANSFER_WRITE_BIT :
4191 VK_ACCESS_TRANSFER_READ_BIT,
4192 upload ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL :
4193 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4194 VK_QUEUE_FAMILY_IGNORED);
4196 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
4197 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
4198 .pImageMemoryBarriers = img_bar,
4199 .imageMemoryBarrierCount = nb_img_bar,
4203 int buf_idx =
FFMIN(
i, (nb_bufs - 1));
4204 int img_idx =
FFMIN(
i, (nb_images - 1));
4207 uint32_t orig_stride = region[
i].bufferRowLength;
4208 region[
i].bufferRowLength /=
desc->comp[
i].step;
4212 vk->CmdCopyBufferToImage(cmd_buf, vkbuf->
buf,
4213 hwf_vk->
img[img_idx],
4214 img_bar[img_idx].newLayout,
4217 vk->CmdCopyImageToBuffer(cmd_buf, hwf_vk->
img[img_idx],
4218 img_bar[img_idx].newLayout,
4222 region[
i].bufferRowLength = orig_stride;
4228 }
else if (!upload) {
4235 for (
int i = 0;
i < nb_bufs;
i++)
4246 switch (
src->format) {
4250 if ((p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY) &&
4251 (p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM))
4256 return vulkan_transfer_data_from_cuda(hwfc,
dst,
src);
4259 if (
src->hw_frames_ctx)
4282 CudaFunctions *cu = cu_internal->
cuda_dl;
4292 err =
CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx));
4296 err = vulkan_export_to_cuda(hwfc,
dst->hw_frames_ctx,
src);
4305 s_w_par[
i].params.fence.value = dst_f->
sem_value[
i] + 0;
4306 s_s_par[
i].params.fence.value = dst_f->
sem_value[
i] + 1;
4309 err =
CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
4310 planes, cuda_dev->stream));
4315 CUDA_MEMCPY2D cpy = {
4316 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
4317 .dstDevice = (CUdeviceptr)
dst->data[
i],
4318 .dstPitch =
dst->linesize[
i],
4321 .srcMemoryType = CU_MEMORYTYPE_ARRAY,
4322 .srcArray = dst_int->cu_array[
i],
4328 cpy.WidthInBytes =
w *
desc->comp[
i].step;
4331 err =
CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream));
4336 err =
CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par,
4337 planes, cuda_dev->stream));
4363 switch (
dst->format) {
4367 if ((p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY) &&
4368 (p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM))
4373 return vulkan_transfer_data_to_cuda(hwfc,
dst,
src);
4376 if (
dst->hw_frames_ctx)