mirror of https://github.com/mpv-player/mpv
vo_gpu: vulkan: open DRM render fd when using VK_KHR_display
While the basic Vulkan Display context can theoretically drive the display without the involvement of any non-Vulkan code, that prevents us from using VAAPI acceleration. When initialising VAAPI without a window system, we need to provide it with an opened DRM render fd corresponding to the device to use. In the context of using VK_KHR_display, that means we need to identify which DRM device matches the selected Vulkan device, and then open its render fd and set the necessary state that VAAPI expects to find. With that done, the normal VAAPI<->Vulkan interop can kick in and we get working acceleration
This commit is contained in:
parent
3bfc37dcb4
commit
b030cfe05f
|
@ -15,11 +15,19 @@
|
|||
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "options/m_config.h"
|
||||
|
||||
#include "context.h"
|
||||
#include "options/m_config.h"
|
||||
#include "utils.h"
|
||||
|
||||
#if HAVE_DRM
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libmpv/render_gl.h"
|
||||
#include "video/out/drm_common.h"
|
||||
#endif
|
||||
|
||||
struct vulkan_display_opts {
|
||||
int display;
|
||||
int mode;
|
||||
|
@ -278,14 +286,83 @@ struct priv {
|
|||
struct vulkan_display_opts *opts;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
||||
#if HAVE_DRM
|
||||
struct mpv_opengl_drm_params_v2 drm_params;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if HAVE_DRM
|
||||
static void open_render_fd(struct ra_ctx *ctx, const char *render_path)
|
||||
{
|
||||
struct priv *p = ctx->priv;
|
||||
p->drm_params.fd = -1;
|
||||
p->drm_params.render_fd = open(render_path, O_RDWR | O_CLOEXEC);
|
||||
if (p->drm_params.render_fd == -1) {
|
||||
MP_WARN(ctx, "Failed to open render node: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static bool drm_setup(struct ra_ctx *ctx, int display_idx,
|
||||
VkPhysicalDevicePCIBusInfoPropertiesEXT *pci_props)
|
||||
{
|
||||
drmDevice *devs[32] = {};
|
||||
int count = drmGetDevices2(0, devs, MP_ARRAY_SIZE(devs));
|
||||
for (int i = 0; i < count; i++) {
|
||||
drmDevice *dev = devs[i];
|
||||
|
||||
if (dev->bustype != DRM_BUS_PCI ||
|
||||
dev->businfo.pci->domain != pci_props->pciDomain ||
|
||||
dev->businfo.pci->bus != pci_props->pciBus ||
|
||||
dev->businfo.pci->dev != pci_props->pciDevice ||
|
||||
dev->businfo.pci->func != pci_props->pciFunction)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Found our matching device.
|
||||
MP_DBG(ctx, "DRM device found for Vulkan device at %04X:%02X:%02X:%02X\n",
|
||||
pci_props->pciDomain, pci_props->pciBus,
|
||||
pci_props->pciDevice, pci_props->pciFunction);
|
||||
|
||||
if (!(dev->available_nodes & 1 << DRM_NODE_RENDER)) {
|
||||
MP_DBG(ctx, "Card does not have a render node.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
open_render_fd(ctx, dev->nodes[DRM_NODE_RENDER]);
|
||||
|
||||
break;
|
||||
}
|
||||
drmFreeDevices(devs, MP_ARRAY_SIZE(devs));
|
||||
|
||||
struct priv *p = ctx->priv;
|
||||
if (p->drm_params.render_fd == -1) {
|
||||
MP_WARN(ctx, "Couldn't open DRM render node for Vulkan device "
|
||||
"at: %04X:%02X:%02X:%02X\n",
|
||||
pci_props->pciDomain, pci_props->pciBus,
|
||||
pci_props->pciDevice, pci_props->pciFunction);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void display_uninit(struct ra_ctx *ctx)
|
||||
{
|
||||
struct priv *p = ctx->priv;
|
||||
|
||||
ra_vk_ctx_uninit(ctx);
|
||||
mpvk_uninit(&p->vk);
|
||||
|
||||
#if HAVE_DRM
|
||||
if (p->drm_params.render_fd != -1) {
|
||||
close(p->drm_params.render_fd);
|
||||
p->drm_params.render_fd = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool display_init(struct ra_ctx *ctx)
|
||||
|
@ -318,6 +395,20 @@ static bool display_init(struct ra_ctx *ctx)
|
|||
goto error;
|
||||
}
|
||||
|
||||
#if HAVE_DRM
|
||||
VkPhysicalDevicePCIBusInfoPropertiesEXT pci_props = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT,
|
||||
};
|
||||
VkPhysicalDeviceProperties2KHR props = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
|
||||
.pNext = &pci_props,
|
||||
};
|
||||
vkGetPhysicalDeviceProperties2(device, &props);
|
||||
|
||||
if (!drm_setup(ctx, display_idx, &pci_props))
|
||||
MP_WARN(ctx, "Failed to set up DRM.\n");
|
||||
#endif
|
||||
|
||||
struct mode_selector selector = {
|
||||
.display_idx = display_idx,
|
||||
.mode_idx = mode_idx,
|
||||
|
@ -351,6 +442,15 @@ static bool display_init(struct ra_ctx *ctx)
|
|||
if (!ra_vk_ctx_init(ctx, vk, params, VK_PRESENT_MODE_FIFO_KHR))
|
||||
goto error;
|
||||
|
||||
#if HAVE_DRM
|
||||
if (p->drm_params.render_fd > -1) {
|
||||
ra_add_native_resource(ctx->ra, "drm_params_v2", &p->drm_params);
|
||||
} else {
|
||||
MP_WARN(ctx,
|
||||
"No DRM render fd available. VAAPI hwaccel will not be usable.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = true;
|
||||
|
||||
done:
|
||||
|
|
Loading…
Reference in New Issue