diff options
author | Lynne <dev@lynne.ee> | 2023-03-14 22:30:18 +0100 |
---|---|---|
committer | Lynne <dev@lynne.ee> | 2023-05-29 00:41:40 +0200 |
commit | 571756bf2fe255a4108360c305cae94866bd6e9f (patch) | |
tree | 226d493cbeab50ab72ecc7cf93407ddad42c4304 | |
parent | e11fd1abdba10df572e9ef0281068983c024ba8e (diff) |
hwcontext_vulkan: use VK_EXT_physical_device_drm to derive DRM to Vulkan
Finally, a way to directly identify a Vulkan device from a DRM device!
-rw-r--r-- | libavutil/hwcontext_vulkan.c | 58 | ||||
-rw-r--r-- | libavutil/vulkan_functions.h | 1 | ||||
-rw-r--r-- | libavutil/vulkan_loader.h | 1 |
3 files changed, 55 insertions, 5 deletions
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c index 7051c5dda8..8cb55b98cc 100644 --- a/libavutil/hwcontext_vulkan.c +++ b/libavutil/hwcontext_vulkan.c @@ -50,6 +50,8 @@ #if CONFIG_VAAPI #include <va/va_drmcommon.h> #endif +#include <sys/sysmacros.h> +#include <sys/stat.h> #include <xf86drm.h> #include <drm_fourcc.h> #include "hwcontext_drm.h" @@ -356,6 +358,7 @@ static const VulkanOptExtension optional_device_exts[] = { { VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, FF_VK_EXT_NO_FLAG }, { VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, FF_VK_EXT_NO_FLAG }, { VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME, FF_VK_EXT_DESCRIPTOR_BUFFER, }, + { VK_EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME, FF_VK_EXT_DEVICE_DRM }, /* Imports/exports */ { VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_MEMORY }, @@ -762,8 +765,11 @@ fail: typedef struct VulkanDeviceSelection { uint8_t uuid[VK_UUID_SIZE]; /* Will use this first unless !has_uuid */ int has_uuid; - const char *name; /* Will use this second unless NULL */ - uint32_t pci_device; /* Will use this third unless 0x0 */ + uint32_t drm_major; /* Will use this second unless !has_drm */ + uint32_t drm_minor; /* Will use this second unless !has_drm */ + uint32_t has_drm; /* has drm node info */ + const char *name; /* Will use this third unless NULL */ + uint32_t pci_device; /* Will use this fourth unless 0x0 */ uint32_t vendor_id; /* Last resort to find something deterministic */ int index; /* Finally fall back to index */ } VulkanDeviceSelection; @@ -790,6 +796,7 @@ static int find_device(AVHWDeviceContext *ctx, VulkanDeviceSelection *select) VkPhysicalDevice *devices = NULL; VkPhysicalDeviceIDProperties *idp = NULL; VkPhysicalDeviceProperties2 *prop = NULL; + VkPhysicalDeviceDrmPropertiesEXT *drm_prop = NULL; AVVulkanDeviceContext *hwctx = ctx->hwctx; ret = vk->EnumeratePhysicalDevices(hwctx->inst, &num, NULL); @@ -822,8 +829,20 @@ static int find_device(AVHWDeviceContext *ctx, VulkanDeviceSelection *select) goto end; } + if (p->vkctx.extensions & FF_VK_EXT_DEVICE_DRM) { + drm_prop = av_calloc(num, sizeof(*drm_prop)); + if (!drm_prop) { + err = AVERROR(ENOMEM); + goto end; + } + } + av_log(ctx, AV_LOG_VERBOSE, "GPU listing:\n"); for (int i = 0; i < num; i++) { + if (p->vkctx.extensions & FF_VK_EXT_DEVICE_DRM) { + drm_prop[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT; + idp[i].pNext = &drm_prop[i]; + } idp[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; prop[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; prop[i].pNext = &idp[i]; @@ -845,6 +864,20 @@ static int find_device(AVHWDeviceContext *ctx, VulkanDeviceSelection *select) av_log(ctx, AV_LOG_ERROR, "Unable to find device by given UUID!\n"); err = AVERROR(ENODEV); goto end; + } else if ((p->vkctx.extensions & FF_VK_EXT_DEVICE_DRM) && select->has_drm) { + for (int i = 0; i < num; i++) { + if ((select->drm_major == drm_prop[i].primaryMajor && + select->drm_minor == drm_prop[i].primaryMinor) || + (select->drm_major == drm_prop[i].renderMajor && + select->drm_minor == drm_prop[i].renderMinor)) { + choice = i; + goto end; + } + } + av_log(ctx, AV_LOG_ERROR, "Unable to find device by given DRM node numbers %i:%i!\n", + select->drm_major, select->drm_minor); + err = AVERROR(ENODEV); + goto end; } else if (select->name) { av_log(ctx, AV_LOG_VERBOSE, "Requested device: %s\n", select->name); for (int i = 0; i < num; i++) { @@ -904,6 +937,7 @@ end: av_free(devices); av_free(prop); av_free(idp); + av_free(drm_prop); return err; } @@ -1648,12 +1682,26 @@ static int vulkan_device_derive(AVHWDeviceContext *ctx, #endif #if CONFIG_LIBDRM case AV_HWDEVICE_TYPE_DRM: { + int err; + struct stat drm_node_info; + drmDevice *drm_dev_info; AVDRMDeviceContext *src_hwctx = src_ctx->hwctx; - drmDevice *drm_dev_info; - int err = drmGetDevice(src_hwctx->fd, &drm_dev_info); + err = fstat(src_hwctx->fd, &drm_node_info); + if (err) { + av_log(ctx, AV_LOG_ERROR, "Unable to get node info from DRM fd: %s!\n", + av_err2str(AVERROR(errno))); + return AVERROR_EXTERNAL; + } + + dev_select.drm_major = major(drm_node_info.st_dev); + dev_select.drm_minor = minor(drm_node_info.st_dev); + dev_select.has_drm = 1; + + err = drmGetDevice(src_hwctx->fd, &drm_dev_info); if (err) { - av_log(ctx, AV_LOG_ERROR, "Unable to get device info from DRM fd!\n"); + av_log(ctx, AV_LOG_ERROR, "Unable to get device info from DRM fd: %s!\n", + av_err2str(AVERROR(errno))); return AVERROR_EXTERNAL; } diff --git a/libavutil/vulkan_functions.h b/libavutil/vulkan_functions.h index 4eccdad3c4..ee0adf427c 100644 --- a/libavutil/vulkan_functions.h +++ b/libavutil/vulkan_functions.h @@ -38,6 +38,7 @@ typedef enum FFVulkanExtensions { FF_VK_EXT_EXTERNAL_WIN32_SEM = 1ULL << 7, /* VK_KHR_external_semaphore_win32 */ #endif FF_VK_EXT_DESCRIPTOR_BUFFER = 1ULL << 8, /* VK_EXT_descriptor_buffer */ + FF_VK_EXT_DEVICE_DRM = 1ULL << 9, /* VK_EXT_physical_device_drm */ FF_VK_EXT_NO_FLAG = 1ULL << 31, } FFVulkanExtensions; diff --git a/libavutil/vulkan_loader.h b/libavutil/vulkan_loader.h index e08777db17..2e6dfb4f4f 100644 --- a/libavutil/vulkan_loader.h +++ b/libavutil/vulkan_loader.h @@ -44,6 +44,7 @@ static inline uint64_t ff_vk_extensions_to_mask(const char * const *extensions, { VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_SEM }, { VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_HOST_MEMORY }, { VK_EXT_DEBUG_UTILS_EXTENSION_NAME, FF_VK_EXT_DEBUG_UTILS }, + { VK_EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME, FF_VK_EXT_DEVICE_DRM }, #ifdef _WIN32 { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_MEMORY }, { VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_SEM }, |