Fix automatic VA DRM driver selection with libva 2.20

This commit is contained in:
Cameron Gutman
2023-10-05 18:12:12 -05:00
parent 5974980aff
commit a2f23b7053
2 changed files with 73 additions and 3 deletions

View File

@@ -7,6 +7,10 @@
#include "utils.h"
#include <streaming/streamutils.h>
#ifdef HAVE_LIBVA_DRM
#include <xf86drm.h>
#endif
#include <SDL_syswm.h>
#include <unistd.h>
@@ -26,6 +30,10 @@ VAAPIRenderer::VAAPIRenderer(int decoderSelectionPass)
SDL_zero(m_PrimeDescriptor);
#endif
#ifdef HAVE_LIBVA_DRM
m_DrmFd = -1;
#endif
SDL_zero(m_OverlayImage);
SDL_zero(m_OverlaySubpicture);
SDL_zero(m_OverlayFormat);
@@ -56,6 +64,12 @@ VAAPIRenderer::~VAAPIRenderer()
}
}
#ifdef HAVE_LIBVA_DRM
if (m_DrmFd >= 0) {
close(m_DrmFd);
}
#endif
if (m_OverlayMutex != nullptr) {
SDL_DestroyMutex(m_OverlayMutex);
}
@@ -109,7 +123,41 @@ VAAPIRenderer::openDisplay(SDL_Window* window)
#if defined(SDL_VIDEO_DRIVER_KMSDRM) && defined(HAVE_LIBVA_DRM) && SDL_VERSION_ATLEAST(2, 0, 15)
else if (info.subsystem == SDL_SYSWM_KMSDRM) {
SDL_assert(info.info.kmsdrm.drm_fd >= 0);
display = vaGetDisplayDRM(info.info.kmsdrm.drm_fd);
// It's possible to enter this function several times as we're probing VA drivers.
// Make sure to only duplicate the DRM FD the first time through.
if (m_DrmFd < 0) {
// If the KMSDRM FD is not a render node FD, open the render node for libva to use.
// Since libva 2.20, using a primary node will fail in vaGetDriverNames().
if (drmGetNodeTypeFromFd(info.info.kmsdrm.drm_fd) != DRM_NODE_RENDER) {
char* renderNodePath = drmGetRenderDeviceNameFromFd(info.info.kmsdrm.drm_fd);
if (renderNodePath) {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Opening render node for VAAPI: %s",
renderNodePath);
m_DrmFd = open(renderNodePath, O_RDWR | O_CLOEXEC);
free(renderNodePath);
if (m_DrmFd < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to open render node: %d",
errno);
return nullptr;
}
}
else {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Failed to get render node path. Using the SDL FD directly.");
m_DrmFd = dup(info.info.kmsdrm.drm_fd);
}
}
else {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"KMSDRM FD is already a render node. Using the SDL FD directly.");
m_DrmFd = dup(info.info.kmsdrm.drm_fd);
}
}
display = vaGetDisplayDRM(m_DrmFd);
if (display == nullptr) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Unable to open DRM display for VAAPI");