mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-13 21:28:01 +02:00
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!
This commit is contained in:
parent
e11fd1abdb
commit
571756bf2f
@ -50,6 +50,8 @@
|
|||||||
#if CONFIG_VAAPI
|
#if CONFIG_VAAPI
|
||||||
#include <va/va_drmcommon.h>
|
#include <va/va_drmcommon.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <sys/sysmacros.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
#include "hwcontext_drm.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_PUSH_DESCRIPTOR_EXTENSION_NAME, FF_VK_EXT_NO_FLAG },
|
||||||
{ VK_KHR_SAMPLER_YCBCR_CONVERSION_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_DESCRIPTOR_BUFFER_EXTENSION_NAME, FF_VK_EXT_DESCRIPTOR_BUFFER, },
|
||||||
|
{ VK_EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME, FF_VK_EXT_DEVICE_DRM },
|
||||||
|
|
||||||
/* Imports/exports */
|
/* Imports/exports */
|
||||||
{ VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_MEMORY },
|
{ VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_MEMORY },
|
||||||
@ -762,8 +765,11 @@ fail:
|
|||||||
typedef struct VulkanDeviceSelection {
|
typedef struct VulkanDeviceSelection {
|
||||||
uint8_t uuid[VK_UUID_SIZE]; /* Will use this first unless !has_uuid */
|
uint8_t uuid[VK_UUID_SIZE]; /* Will use this first unless !has_uuid */
|
||||||
int has_uuid;
|
int has_uuid;
|
||||||
const char *name; /* Will use this second unless NULL */
|
uint32_t drm_major; /* Will use this second unless !has_drm */
|
||||||
uint32_t pci_device; /* Will use this third unless 0x0 */
|
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 */
|
uint32_t vendor_id; /* Last resort to find something deterministic */
|
||||||
int index; /* Finally fall back to index */
|
int index; /* Finally fall back to index */
|
||||||
} VulkanDeviceSelection;
|
} VulkanDeviceSelection;
|
||||||
@ -790,6 +796,7 @@ static int find_device(AVHWDeviceContext *ctx, VulkanDeviceSelection *select)
|
|||||||
VkPhysicalDevice *devices = NULL;
|
VkPhysicalDevice *devices = NULL;
|
||||||
VkPhysicalDeviceIDProperties *idp = NULL;
|
VkPhysicalDeviceIDProperties *idp = NULL;
|
||||||
VkPhysicalDeviceProperties2 *prop = NULL;
|
VkPhysicalDeviceProperties2 *prop = NULL;
|
||||||
|
VkPhysicalDeviceDrmPropertiesEXT *drm_prop = NULL;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
|
|
||||||
ret = vk->EnumeratePhysicalDevices(hwctx->inst, &num, NULL);
|
ret = vk->EnumeratePhysicalDevices(hwctx->inst, &num, NULL);
|
||||||
@ -822,8 +829,20 @@ static int find_device(AVHWDeviceContext *ctx, VulkanDeviceSelection *select)
|
|||||||
goto end;
|
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");
|
av_log(ctx, AV_LOG_VERBOSE, "GPU listing:\n");
|
||||||
for (int i = 0; i < num; i++) {
|
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;
|
idp[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
|
||||||
prop[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
prop[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||||
prop[i].pNext = &idp[i];
|
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");
|
av_log(ctx, AV_LOG_ERROR, "Unable to find device by given UUID!\n");
|
||||||
err = AVERROR(ENODEV);
|
err = AVERROR(ENODEV);
|
||||||
goto end;
|
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) {
|
} else if (select->name) {
|
||||||
av_log(ctx, AV_LOG_VERBOSE, "Requested device: %s\n", select->name);
|
av_log(ctx, AV_LOG_VERBOSE, "Requested device: %s\n", select->name);
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
@ -904,6 +937,7 @@ end:
|
|||||||
av_free(devices);
|
av_free(devices);
|
||||||
av_free(prop);
|
av_free(prop);
|
||||||
av_free(idp);
|
av_free(idp);
|
||||||
|
av_free(drm_prop);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -1648,12 +1682,26 @@ static int vulkan_device_derive(AVHWDeviceContext *ctx,
|
|||||||
#endif
|
#endif
|
||||||
#if CONFIG_LIBDRM
|
#if CONFIG_LIBDRM
|
||||||
case AV_HWDEVICE_TYPE_DRM: {
|
case AV_HWDEVICE_TYPE_DRM: {
|
||||||
|
int err;
|
||||||
|
struct stat drm_node_info;
|
||||||
|
drmDevice *drm_dev_info;
|
||||||
AVDRMDeviceContext *src_hwctx = src_ctx->hwctx;
|
AVDRMDeviceContext *src_hwctx = src_ctx->hwctx;
|
||||||
|
|
||||||
drmDevice *drm_dev_info;
|
err = fstat(src_hwctx->fd, &drm_node_info);
|
||||||
int err = drmGetDevice(src_hwctx->fd, &drm_dev_info);
|
|
||||||
if (err) {
|
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 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: %s!\n",
|
||||||
|
av_err2str(AVERROR(errno)));
|
||||||
return AVERROR_EXTERNAL;
|
return AVERROR_EXTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ typedef enum FFVulkanExtensions {
|
|||||||
FF_VK_EXT_EXTERNAL_WIN32_SEM = 1ULL << 7, /* VK_KHR_external_semaphore_win32 */
|
FF_VK_EXT_EXTERNAL_WIN32_SEM = 1ULL << 7, /* VK_KHR_external_semaphore_win32 */
|
||||||
#endif
|
#endif
|
||||||
FF_VK_EXT_DESCRIPTOR_BUFFER = 1ULL << 8, /* VK_EXT_descriptor_buffer */
|
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,
|
FF_VK_EXT_NO_FLAG = 1ULL << 31,
|
||||||
} FFVulkanExtensions;
|
} FFVulkanExtensions;
|
||||||
|
@ -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_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_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_HOST_MEMORY },
|
||||||
{ VK_EXT_DEBUG_UTILS_EXTENSION_NAME, FF_VK_EXT_DEBUG_UTILS },
|
{ 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
|
#ifdef _WIN32
|
||||||
{ VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_MEMORY },
|
{ 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 },
|
{ VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_SEM },
|
||||||
|
Loading…
Reference in New Issue
Block a user